I am having no luck finding the issue of data binding not working. I have two user controls. The user control that uses the obervablecollection works fine. The user control bound to an object doesnt. If i assign the value to the text the value does appear. During debugging I can verify that the values are correct.
This logic is following Paul Sheriff and a few posts from this web site.
My coworkers dont program in C# so they cant help. Im missing something but have no idea what it is.
ViewModel class that inherits from INotifyPropertyChanged:
ParameterSettings _ps;
public ParameterSettings DetailData
{
get { return _ps; }
set
{
_ps = value;
RaisePropertyChanged("DetailData");
}
}
public async Task GetParameters()
{
var pm = new ParameterManager();
DetailData = new ParameterSettings();
await pm.GetLoginCredentials(_ps);
}
this is the code the user control.
ViewModels.ParameterSettingsVm _viewModel;
public ParameterSettingsUc()
{
this.InitializeComponent();
_viewModel = (ParameterSettingsVm)Resources["viewModel"];
var bounds = Window.Current.Bounds;
this.CancelBtn.Width = bounds.Width * .5;
this.SaveBtn.Width = bounds.Width * .5;
}
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
{
await _viewModel.GetParameters();
//UserNameBx.Text = _viewModel.DetailData.UserLogin; //textbox gets filled in.
}
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SiteManager.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:VM="using:SiteManager.ViewModels"
x:Class="SiteManager.Views.ParameterSettingsUc"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
Loaded="UserControl_Loaded">
<UserControl.Resources>
<VM:ParameterSettingsVm x:Key="viewModel"></VM:ParameterSettingsVm>
</UserControl.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" >
<TextBox Header="Login:" VerticalAlignment="Center" Margin="2,10,0,0" Grid.Row="0" x:Name="UserNameBx" Text="{Binding Path=DetailData.UserLogin, Mode=TwoWay, UpdateSourceTrigger=Default}" >
<TextBox.DataContext>
<VM:ParameterSettingsVm/>
</TextBox.DataContext>
</TextBox>
I would change is it to make the ViewModel a property.
ViewModels.ParameterSettingsVm _viewModel {get;set;}
public ParameterSettingsUc()
{
this.InitializeComponent();
_viewModel = (ParameterSettingsVm)Resources["viewModel"];
var bounds = Window.Current.Bounds;
this.CancelBtn.Width = bounds.Width * .5;
this.SaveBtn.Width = bounds.Width * .5;
}
private async void UserControl_Loaded(object sender, RoutedEventArgs e)
{
await _viewModel.GetParameters();
//UserNameBx.Text = _viewModel.DetailData.UserLogin; //textbox gets filled in.
}
and then I would set the _viewModel as the data context for the textBox. Oh and set the dataContext for the usercontrol to self, like this.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SiteManager.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:VM="using:SiteManager.ViewModels"
x:Class="SiteManager.Views.ParameterSettingsUc"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Loaded="UserControl_Loaded">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" >
<TextBox Header="Login:" VerticalAlignment="Center"
Margin="2,10,0,0" Grid.Row="0" x:Name="UserNameBx"
Text="{Binding Path=DetailData.UserLogin, Mode=TwoWay, UpdateSourceTrigger=Default}"
DataContext={Binding _viewModel}>
</TextBox>
This may not be what you're trying to do though. I just assumed since you're creating _viewModel you would want to use it.
From microsoft virtual academy. Used x:bind its faster and less verbose.
mva.microsoft.com/en-US/training-courses/windows-10-data-binding-14579. Each class property i made into a INotfiyChange property of the vm.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:SiteManager.Views"
xmlns:VM="using:SiteManager.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:diag="using:System.Diagnostics"
x:Class="SiteManager.Views.ParameterSettingsUc"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
Loaded="UserControl_Loaded" >
<UserControl.DataContext>
<VM:ParameterSettingsVm></VM:ParameterSettingsVm>
</UserControl.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" >
<Grid.RowDefinitions>
<RowDefinition Height="70"/>
<RowDefinition Height="70"/>
<RowDefinition Height="70"/>
<RowDefinition Height="70"/>
</Grid.RowDefinitions>
<TextBox Header="Login:" VerticalAlignment="Center" Margin="2,10,0,0" Grid.Row="0" x:Name="UserNameBx" Text="{x:Bind Path=_viewModel.UserLogin, Mode=TwoWay }" > </TextBox>
<TextBox Header="Password:" VerticalAlignment="Center" Margin="1" Grid.Row="1" x:Name="PasswordBx" Text="{x:Bind Path=_viewModel.UserPassword, Mode=TwoWay }"> </TextBox>
<TextBox Header="Mature Key:" VerticalAlignment="Center" Margin="1" Grid.Row="2" x:Name="MatureKeyBx" Text="{x:Bind Path=_viewModel.MatureKey, Mode=TwoWay }"> </TextBox>
public sealed partial class ParameterSettingsUc : UserControl
{
ParameterSettingsVm _viewModel { get; set; } = new ParameterSettingsVm();
string _userLogin;
public string UserLogin
{
get { return _userLogin; }
set
{
_userLogin = value;
RaisePropertyChanged("UserLogin");
}
}
Related
I have two TextBoxes and a ScrollBar. With the scrollbar I want to scroll both TextBoxes. The maximum value of the scrollbar is the maximum of the maximum values of the two textbox scrollbars.
My problem is that if the text inside a TextBox is not bigger than the textbox itself, the text won't scroll. How can I force the text to be scrollable?
Here is my code:
<Window x:Class="HorizontalScrollViewerTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800"
Loaded="MainWindow_OnLoaded">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0"
x:Name="UpperTextBox"
Text="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"
HorizontalScrollBarVisibility="Hidden"/>
<TextBox Grid.Row="1"
x:Name="LowerTextBox"
Text="abc"
HorizontalScrollBarVisibility="Hidden"/>
<ScrollBar Grid.Row="2"
x:Name="ScrollBar"
Orientation="Horizontal"
Value="{Binding ScrollValue, RelativeSource={RelativeSource AncestorType=Window}}"/>
</Grid>
using System;
using System.Windows;
namespace HorizontalScrollViewerTest
{
public partial class MainWindow
{
public static readonly DependencyProperty ScrollValueProperty = DependencyProperty.Register(
"ScrollValue", typeof(int), typeof(MainWindow), new PropertyMetadata(default(int), ScrollValueChanged));
private static void ScrollValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MainWindow).UpperTextBox.ScrollToHorizontalOffset((int)e.NewValue);
(d as MainWindow).LowerTextBox.ScrollToHorizontalOffset((int)e.NewValue);
}
public int ScrollValue
{
get => (int) GetValue(ScrollValueProperty);
set => SetValue(ScrollValueProperty, value);
}
public MainWindow()
{
InitializeComponent();
}
private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
var maxExtent = Math.Max(UpperTextBox.ExtentWidth, LowerTextBox.ExtentWidth);
ScrollBar.Maximum = Math.Max(ScrollBar.ActualWidth, maxExtent) - ScrollBar.ActualWidth;
ScrollBar.ViewportSize = ScrollBar.ActualWidth;
}
}
}
Can't you just wrap these two TextBoxes in a ScrollViewer?
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<ScrollViewer CanContentScroll="true" HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden" Grid.Column="1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBox Grid.Row="0"
x:Name="UpperTextBox"
Text="abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz"/>
<TextBox Grid.Row="1"
x:Name="LowerTextBox"
Text="abc"/>
</Grid>
</ScrollViewer>
</Grid>
If you cannot wrap the TextBoxes you can apply a Margin to them instead of using ScrollToHorizontalOffset:
private static void ScrollValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as MainWindow).UpperTextBox.Margin = new Thickness(-1 * (int)e.NewValue, 0, 0, 0);
(d as MainWindow).LowerTextBox.Margin = new Thickness(-1 * (int)e.NewValue, 0, 0, 0);
//(d as MainWindow).UpperTextBox.ScrollToHorizontalOffset((int)e.NewValue * 100);
//(d as MainWindow).LowerTextBox.ScrollToHorizontalOffset((int)e.NewValue * 100);
}
You should also compute the ScrollBar.Maximum and the ScrollBar.ViewportSize each time one of the component is resized:
<ScrollBar Grid.Row="2" SizeChanged="MainWindow_OnLoaded" [...]/>
I implemented the solution for this question, in a window with XAML given below. I am trying to make a scrolling marquee text effect for a label:
<Window x:Class="WpfMarqueeText.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpfMarqueeText="clr-namespace:WpfMarqueeText"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="200"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="500"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="0" Grid.Column="0" Background="Aqua">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<Ellipse Grid.Column="0" Margin="5,3,5,3" Fill="#b933ad"/>
<Label Grid.Column="0" Content="Z" Foreground="White" FontFamily="HelveticaBold" FontSize="150" FontWeight="Bold" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="5,3,5,3"/>
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Some Info:" FontFamily="HelveticaBold" FontSize="18" FontWeight="Bold" Margin="5,3,5,3"/>
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Horizontal" x:Name="stack">
<StackPanel.Resources>
<wpfMarqueeText:NegatingConverter x:Key="NegatingConverter" />
<Storyboard x:Key="slide">
<DoubleAnimation From="0" To="{Binding Width, ElementName=canvas, Converter={StaticResource NegatingConverter}}" Duration="00:00:10"
Storyboard.TargetProperty="X"
Storyboard.TargetName="transferCurreny"
RepeatBehavior="Forever"/>
</Storyboard>
</StackPanel.Resources>
<StackPanel.RenderTransform>
<TranslateTransform x:Name="transferCurreny" X="0"/>
</StackPanel.RenderTransform>
<StackPanel.Triggers>
<EventTrigger RoutedEvent="StackPanel.Loaded">
<BeginStoryboard Storyboard="{StaticResource slide}" />
</EventTrigger>
<EventTrigger RoutedEvent="StackPanel.SizeChanged">
<BeginStoryboard Storyboard="{StaticResource slide}" />
</EventTrigger>
</StackPanel.Triggers>
<Canvas x:Name="canvas" Width="{Binding ActualWidth, ElementName=stack}">
<Label FontFamily="HelveticaBold" FontSize="18" Margin="5,3,5,3" x:Name="Label1" Content="Blah blah blah" Canvas.Left="0"/>
<Label Name="Label2" Content="{Binding Content, ElementName=Label1}" FontFamily="HelveticaBold" FontSize="18" Margin="5,3,5,3" Canvas.Left="{Binding ActualWidth, ElementName=stack}"/>
</Canvas>
</StackPanel>
</Grid>
</Grid>
</Grid>
</Grid>
</Window>
You must also define the NegatingConverter class in the code-behind:
public class NegatingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double)
{
return -((double)value);
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is double)
{
return +(double)value;
}
return value;
}
}
This produces the desired efect, however the text animation scrolls over the other UI elements as seen in the images below (sorry, I don't have enough rep to post images):
http://tinypic.com/r/df8zeu/9
http://tinypic.com/r/2inc3r/9
So, is there any way to fix the animation so that the text only scrolls within the boundary of the grid column it is contained within, or within the boundaries of the label itself? Thanks for any help!
This is a quick and dirty-solution:
Change your Label to
<Label Grid.Row="0" Grid.Column="0" Content="Some Info:" FontFamily="HelveticaBold" FontSize="18" FontWeight="Bold" Margin="5,3,5,3" Panel.ZIndex="99" Background="Aqua"/>
The Panel.ZIndex brings the Label to front. And making the Background not Transparent gives the desired look. The boundries are still not perfect, but this should give you a clue on how to handle Layers
The article linked by Akanksha in response to my OP shows how to create a user control that produces a clean, scrolling text effect. You can also specify 4 different scroll directions, left <-> right and up <-> down. I'll give my implementation here for others:
XAML for MarqueeTextUserControl:
<UserControl x:Class="AaronLuna.Common.UI.UserControls.MarqueeTextUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" Loaded="UserControl_Loaded">
<Canvas ClipToBounds="True" Name="CanvasMain">
<TextBlock Name="TextBlockMain"/>
</Canvas>
</UserControl>
Code for MarqueeTextUserControl:
namespace AaronLuna.Common.UI.UserControls
{
public partial class MarqueeTextUserControl
{
public MarqueeTextUserControl()
{
InitializeComponent();
CanvasMain.Height = Height;
CanvasMain.Width = Width;
}
public ScrollDirection ScrollDirection { get; set; }
public double ScrollDurationInSeconds { get; set; }
public String Text { set { TextBlockMain.Text = value; }}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
ScrollText(ScrollDirection);
}
public void ScrollText(ScrollDirection scrollDirection)
{
switch (scrollDirection)
{
case ScrollDirection.LeftToRight:
LeftToRightMarquee();
break;
case ScrollDirection.RightToLeft:
RightToLeftMarquee();
break;
case ScrollDirection.TopToBottom:
TopToBottomMarquee();
break;
case ScrollDirection.BottomToTop:
BottomToTopMarquee();
break;
}
}
private void LeftToRightMarquee()
{
double height = CanvasMain.ActualHeight - TextBlockMain.ActualHeight;
TextBlockMain.Margin = new Thickness(0, height/2, 0, 0);
var doubleAnimation = new DoubleAnimation
{
From = -TextBlockMain.ActualWidth,
To = CanvasMain.ActualWidth,
RepeatBehavior = RepeatBehavior.Forever,
Duration = new Duration(TimeSpan.FromSeconds(ScrollDurationInSeconds))
};
TextBlockMain.BeginAnimation(Canvas.LeftProperty, doubleAnimation);
}
private void RightToLeftMarquee()
{
double height = CanvasMain.ActualHeight - TextBlockMain.ActualHeight;
TextBlockMain.Margin = new Thickness(0, height/2, 0, 0);
var doubleAnimation = new DoubleAnimation
{
From = -TextBlockMain.ActualWidth,
To = CanvasMain.ActualWidth,
RepeatBehavior = RepeatBehavior.Forever,
Duration = new Duration(TimeSpan.FromSeconds(ScrollDurationInSeconds))
};
TextBlockMain.BeginAnimation(Canvas.RightProperty, doubleAnimation);
}
private void TopToBottomMarquee()
{
double width = CanvasMain.ActualWidth - TextBlockMain.ActualWidth;
TextBlockMain.Margin = new Thickness(width/2, 0, 0, 0);
var doubleAnimation = new DoubleAnimation
{
From = -TextBlockMain.ActualHeight,
To = CanvasMain.ActualHeight,
RepeatBehavior = RepeatBehavior.Forever,
Duration = new Duration(TimeSpan.FromSeconds(ScrollDurationInSeconds))
};
TextBlockMain.BeginAnimation(Canvas.TopProperty, doubleAnimation);
}
private void BottomToTopMarquee()
{
double width = CanvasMain.ActualWidth - TextBlockMain.ActualWidth;
TextBlockMain.Margin = new Thickness(width/2, 0, 0, 0);
var doubleAnimation = new DoubleAnimation
{
From = -TextBlockMain.ActualHeight,
To = CanvasMain.ActualHeight,
RepeatBehavior = RepeatBehavior.Forever,
Duration = new Duration(TimeSpan.FromSeconds(ScrollDurationInSeconds))
};
TextBlockMain.BeginAnimation(Canvas.BottomProperty, doubleAnimation);
}
}
public enum ScrollDirection
{
LeftToRight,
RightToLeft,
TopToBottom,
BottomToTop
}
}
Client XAML:
<UserControl x:Class="MarqueeTextExampleUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:userControls="clr-namespace:AaronLuna.Common.UI.UserControls;assembly=AaronLuna.Common"
mc:Ignorable="d">
<DockPanel>
<Label Content="Some Info:"/>
<userControls:MarqueeTextUserControl x:Name="MarqueeTextBlock"/>
</DockPanel>
</UserControl>
Client Code:
MarqueeTextBlock.Text = "Blah blah blah";
MarqueeTextBlock.ScrollDirection = ScrollDirection.RightToLeft;
MarqueeTextBlock.ScrollDurationInSeconds = 10;
In my Windows Phone 8.1 app I'm creating a CustomPage and then navigating to it, all in code behind. My CustomPage class is:
using Windows.UI.Xaml.Controls;
namespace TestApp {
public class CustomPage : Page {
public CustomPage() {
this.BuildPage();
}
private void BuildPage() {
var panel = new StackPanel();
panel.Children.Add(new TextBlock { Text = "Hello World" });
this.Content = panel;
}
}
}
And then in my MainPage.xaml.cs I'm doing this:
CustomPage myNewPage = new CustomPage();
Frame.Navigate(myNewPage.GetType());
However this throws a System.TypeLoadException exception - Could not find Windows Runtime type 'Windows.Foundation'
If I don't do a CustomPage class just a Page class, it works fine, but I need to create a CustomPage class, how could I solve this?
UPDATE
This is the Stack Trace
MyCustomClass.DLL!HelpingTool.NavigateToNewPage() Line 50 C#
MyCustomClass.DLL!HelpingTool.InitializeToolset() Line 23 C#
MyCustomClass.DLL!HelpingTool.HelpingTool(Windows.UI.Xaml.Controls.Page mainPage = {TestApp.MainPage}) Line 18 C#
TestApp.exe!TestApp.MainPage.Button_Click(object sender = {Windows.UI.Xaml.Controls.Button}, Windows.UI.Xaml.RoutedEventArgs e = {Windows.UI.Xaml.RoutedEventArgs}) Line 88 C#
And the content of my MainPage.xaml
<Page
x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Loaded="Page_Loaded"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="myGrid" Grid.Row="0">
<TextBlock x:Name="OutputText">
Output will appear here <LineBreak />
</TextBlock>
</Grid>
<ScrollViewer Grid.Row="1" VerticalAlignment="Stretch">
<Button Content="Do something" Click="Button_Click" HorizontalAlignment="Center" />
</ScrollViewer>
</Grid>
</Page>
I create a popup in my windows phone 8 application but my popup take only 1/2 of the width screen, why ?
Xmal of my popup :
<UserControl x:Class="PhoneApp1.PopupRename"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}" d:DesignWidth="480" d:DesignHeight="170">
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button x:Name="CancelButton" Content="Cancel" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="0"/>
<Button x:Name="ValideButton" Content="Valider" Margin="0,0,0,0" VerticalAlignment="Top" Grid.Row="1" Grid.Column="1"/>
<TextBox x:Name="ValueTextBox" Margin="0,5,0,5" TextWrapping="Wrap" Text="" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" />
</Grid>
And i use this c# code :
Popup renamePopup = new Popup();
renamePopup.VerticalOffset = 100;
renamePopup.HorizontalOffset = 10;
PopupRename popupRename = new PopupRename();
renamePopup.Child = popupRename;
renamePopup.IsOpen = true;
popupRename.ValideButton.Click += (s, args) =>
{
renamePopup.IsOpen = false;
//this.text.Text = Mycontrol.tbx.Text;
};
popupRename.CancelButton.Click += (s, args) => { renamePopup.IsOpen = false; };
You must set your popup width to full width:
Width = (Application.Current.RootVisual as PhoneApplicationFrame).ActualWidth
In your example you also can use LayoutRoot.ActualWidth
I am creating Windows Phone 8 app working with Nokia Mix Radio SDK. I have Listbox contains Genres. Each item (genre) in the ListBox has CheckBox, so that user can select only items he wants to listen to. How can I know what genres user selected?
Here is my XAML:
<phone:PhoneApplicationPage
x:Class="MusicApp.GenrePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox x:Name="GenresListBox" Grid.Row="0" >
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="1" Content="Button" HorizontalAlignment="Left" Name="SelectButton" VerticalAlignment="Top" Click="SelectButton_Click"/>
</Grid>
</Grid>
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
namespace MusicApp
{
public partial class GenrePage : PhoneApplicationPage
{
public GenrePage()
{
InitializeComponent();
}
private async void GetGenres()
{
var genres = await App.GetClient().GetGenresAsync();
GenresListBox.ItemsSource = genres;
if (genres.Result == null || genres.Count == 0)
{
MessageBox.Show("No results available");
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
GetGenres();
}
private void SelectButton_Click(object sender, RoutedEventArgs e)
{
var selectedGenres = GenresListBox.SelectedItems;
}
}
}
I did little change in your code. try this it help you
xaml
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox x:Name="GenresListBox" Grid.Row="0" SelectionChanged ="GenresListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Button Grid.Row="1" Content="Button" HorizontalAlignment="Left" Name="SelectButton" VerticalAlignment="Top" Click="SelectButton_Click"/>
</Grid>
IN Code Beind
private void GenresListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (GenresListBox.SelectedIndex == -1)
return;
}
private void SelectButton_Click(object sender, RoutedEventArgs e)
{
var selectedGenres = GenresListBox.SelectedItem;
}
I solved my problem using Windows Phone Toolkit's LongListMultiSelector.
This is how it's going to look like:
Now my XAML is:
<phone:PhoneApplicationPage
x:Class="MusicApp.GenrePage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<toolkit:LongListMultiSelector x:Name="GenresListBox" Grid.Row="0" >
<toolkit:LongListMultiSelector.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
</toolkit:LongListMultiSelector.ItemTemplate>
</toolkit:LongListMultiSelector>
<Button Grid.Row="1" Content="Button" HorizontalAlignment="Left" Name="SelectButton" VerticalAlignment="Top" Click="SelectButton_Click"/>
</Grid>
</Grid>
And code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using Nokia.Music.Types;
namespace MusicApp
{
public partial class GenrePage : PhoneApplicationPage
{
public GenrePage()
{
InitializeComponent();
}
private async void GetGenres()
{
var genres = await App.GetClient().GetGenresAsync();
GenresListBox.ItemsSource = genres;
if (genres.Result == null || genres.Count == 0)
{
MessageBox.Show("No results available");
}
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
GetGenres();
}
private void SelectButton_Click(object sender, RoutedEventArgs e)
{
var genres = GenresListBox.SelectedItems;
}
}
}