Two UserControls, one binds, one doesn't - xaml
I have two very simple UserControls in a simple WinRT demo project. No Viewmodel--mostly just colored boxes for layout exploration. The first UserControl I created works fine. The second, very similar one, won't bind to any properties--it shows up as blank.
The first UserControl looks like this:
<UserControl
x:Class="Demo.SmallStartTile"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Demo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="SmallStartTileUC"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid x:Name="SmallTileGrid"
Margin="0,0,8,8"
Background="{Binding Background, ElementName=SmallStartTileUC}"
>
<Rectangle
Stroke="{Binding BorderBrush, ElementName=SmallStartTileUC}"
Grid.RowSpan="2"
/>
<TextBlock x:Name="SmallTileTitle"
Text="{Binding TileText, ElementName=SmallStartTileUC}"
Style="{StaticResource SmallTileHeader}"/>
<Path x:Name="IconPath"
Style="{StaticResource SmallTileIcon}"
Data="{Binding TileIconPathData, ElementName=SmallStartTileUC}" />
</Grid>
</UserControl>
namespace Demo
{
public sealed partial class SmallStartTile : UserControl
{
public static DependencyProperty TileTextProperty = DependencyProperty.Register("TileText", typeof(string), typeof(SmallStartTile), new PropertyMetadata("tile content"));
public string TileText
{
get { return (string)GetValue(TileTextProperty); }
set { SetValue(TileTextProperty, value); }
}
public static DependencyProperty TileIconPathDataProperty = DependencyProperty.Register("TileIconPathData", typeof(string), typeof(SmallStartTile), new PropertyMetadata("F0"));
public string TileIconPathData
{
get { return (string)GetValue(TileIconPathDataProperty); }
set { SetValue(TileIconPathDataProperty, value); }
}
public SmallStartTile()
{
this.InitializeComponent();
}
}
}
And the second one, which I made just like the first one by clicking Add New Item and picking UserControl in Blend:
<UserControl
x:Class="Demo.SmallMediaTile"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Demo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Name="SmallMediaTileUC"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid
Margin="0,0,8,8"
Background="{Binding Background, ElementName=SmallMediaTileUC}"
>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle
Stroke="{Binding BorderBrush, ElementName=SmallMediaTileUC}"
Grid.RowSpan="2"
/>
<Viewbox
Margin="30"
Child="{Binding Content, ElementName=SmallMediaTileUC}">
</Viewbox>
<TextBlock
Grid.Row="1"
Text="{Binding SourceText, ElementName=SmallMediaTileUC}"
Style="{StaticResource SmallMusicTileHeader}"/>
</Grid>
</UserControl>
namespace Demo
{
public sealed partial class SmallMediaTile : UserControl
{
public static DependencyProperty SourceTextProperty = DependencyProperty.Register("SourceText", typeof(string), typeof(SmallMediaTile), new PropertyMetadata("source"));
public string SourceText
{
get { return (string)GetValue(SourceTextProperty); }
set { SetValue(SourceTextProperty, value); }
}
public SmallMediaTile()
{
this.InitializeComponent();
}
}
}
I use the UserControl in the main Page like this:
<local:SmallMediaTile x:Name="Source1Tile"
Grid.Column="0" Grid.Row="0"
SourceText="Radio"
Background="Blue"
BorderBrush="Red">
<local:SmallMediaTile.Content>
<Canvas x:Name="radio_icon" Height="68" Width="34">
<Path Data="F1M299.6182,396.2988C299.6182,389.7208,297.0722,383.5548,292.4572,378.8398L288.6162,382.6758C292.2022,386.3718,294.1842,391.1778,294.1842,396.2988C294.1842,401.4238,292.2022,406.2368,288.6162,409.9328L292.4572,413.7738C297.0722,409.0538,299.6182,402.8808,299.6182,396.2988" Fill="White" Height="34.934" Canvas.Left="0" Stretch="Fill" Canvas.Top="16.501" Width="11.002"/>
<Path Data="F1M311.1738,396.2988C311.1738,386.6278,307.4348,377.5528,300.6788,370.6208L296.8258,374.4618C302.5658,380.3698,305.7398,388.0798,305.7398,396.2988C305.7398,404.5218,302.5658,412.2298,296.8258,418.1428L300.6788,421.9898C307.4348,415.0498,311.1738,405.9718,311.1738,396.2988" Fill="White" Height="51.369" Canvas.Left="8.21" Stretch="Fill" Canvas.Top="8.282" Width="14.348"/>
<Path Data="F1M322.7578,396.2988C322.7578,383.5298,317.8508,371.5348,308.9638,362.3388L305.1168,366.1748C312.9758,374.3538,317.3338,384.9778,317.3338,396.2988C317.3338,407.6208,312.9758,418.2488,305.1168,426.4268L308.9638,430.2748C317.8508,421.0698,322.7578,409.0798,322.7578,396.2988" Fill="White" Height="67.936" Canvas.Left="16.501" Stretch="Fill" Canvas.Top="0" Width="17.641"/>
</Canvas>
</local:SmallMediaTile.Content>
</local:SmallMediaTile>
The first one picks up all the properties and displays like I expect, but the second one only picks up the Viewbox content. I've looked through SO and been googling but can't figure out what the problem is. Sorry if this is longwinded.
Your root Grid is set as the Content of the UserControl while the Viewbox you have is trying to bind its Child property to the Content of the UserControl that is its ascendant. That is not allowed since the root Grid is already a parent of the UserControl and XAML controls can only exist in one place in the UI.
As noted, the problem is the UserControl's content can only be set once. When I bind the Viewbox Content to the UserControl content, the existing XAML is replaced. So, a blank box but for what I'm passing in. I guess to do what I had hoped, I'd need to make a custom control. Thanks for the help!
Related
How to bind properties for a custom user control properly in avalonia ui
I am trying to display a text on a custome user control. I want that text to be passed via a mainview this is the code I have: MainView.axaml <cc:Slot Grid.Row="0" Grid.Column="1" Dot="Number one"/> <cc:Slot Grid.Row="0" Grid.Column="2" Dot="Number two"/> This is my custom user control: Slot.axaml <UserControl xmlns="https://github.com/avaloniaui" 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" xmlns:controls="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" xmlns:cc="clr-namespace:Diagnostica.CustomControls;assembly=Diagnostica.CustomControls" x:Class="Diagnostica.CustomControls.OmniSlot"> <Button> <TextBlock Text="{Binding Dot}"/> </Button> </Grid> </Button> </UserControl> and its .cs file" Slot.axaml.cs public string Dot { get => GetValue(DotProperty); set => SetValue(DotProperty, value); } public static readonly StyledProperty<string> DotProperty = AvaloniaProperty.Register<Slot, string>(nameof(Dot), defaultValue: "Black"); what i get like this is a disabled box. How can this get fixed?
View: <Rectangle Stroke="{TemplateBinding DotColor}" StrokeThickness="2" Width="20" Height="20" Fill="{TemplateBinding DotColorBrush}" VerticalAlignment="Top" HorizontalAlignment="Right"/> ViewModel: public static readonly StyledProperty<string> DotColorProperty = AvaloniaProperty.Register<OmniSlotControl, string>(nameof(DotColor), "Red"); public string DotColor { get => GetValue(DotColorProperty); set { SetValue(DotColorProperty, value); DotColorBrush = Avalonia.Media.Brush.Parse(value); } }
Update UserControl Textblock text from mainpage.xaml
I am writing a Windows Phone 8.1 Silverlight App. I made a user control NotificationsIconUserControl. It just contains a BELL/ALARM icon and textblock to display number of unread notifications. I want to update this textblock text from mainpage.xaml How to do this? I tried using usercontrol expose properties but its the opposite thing. Also tried help from this question. how to use dependency property. Please edit the code below: Usercontrol XAML: <Grid x:Name="LayoutRoot" Background="Transparent" Height="Auto" Width="Auto"> <Image Name="Alarm_Icon" Source="/Images/Status/Notification_Icon_1.png"> </Image> <Ellipse Name="Counter_Icon" Height="45" Width="45" Margin="60,14,-6,50" StrokeThickness="0" Fill="{StaticResource DefaultTheme_IndianRedColor}"> </Ellipse> <TextBlock Name="Counter_Label" Foreground="{StaticResource DefaultTheme_LightColor}" FontSize="30" HorizontalAlignment="Center" VerticalAlignment="Center" TextAlignment="Center" Margin="75,20,8,58"/> </Grid> Mainpage XAML part: xmlns:MyUserControls="clr-namespace:Project.Custom.UserControls"> Mainpage .cs part: private void ConfigureNotificationsIcon() { int NotificationsCounter = 4; NotificationsIconUserControl NotificationsIconUserControlObject = new NotificationsIconUserControl(); NotificationsIconUserControlObject.Counter_Label.Text = NotificationsCounter.ToString(); }
I checked your code and its working completely.... ANd for the part of adding a Dependency property, write the following in the .cs file of UserControl public partial class NotificationIconUserControl : UserControl { public NotificationIconUserControl() { InitializeComponent(); } public string NotificationLabel { get { return (string)GetValue(NotificationLabelProperty); } set { SetValue(NotificationLabelProperty, value); } } // Using a DependencyProperty as the backing store for Spacing. This enables animation, styling, binding, etc... public static readonly DependencyProperty NotificationLabelProperty = DependencyProperty.Register("NotificationLabel", typeof(string), typeof(NotificationIconUserControl), new PropertyMetadata("hellllo")); } After that you can use TemplateBinding to do your job
Create a component and reuse it in Windows phone 8.1
I want to create some components and reuse them in different pages, put more than one in a page, etc. For example, I want to create a component that contains an image, some text, etc. The position of the elements are fixed, but I will change the image, the text... I mean, in a same page I want to put three circles with different image and text... What is the best way to do it? I've found UserControl, but I'm unable to call a method from another page to change something. This is my component XAML <UserControl x:Class="aa.Components.CircularGraph" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:Components" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> <Grid Name="view"> <Image Name="imageGraph" Source="../Assets/aa/circuloGris.png" /> <StackPanel Orientation="Vertical"> <TextBlock Name="firstLine" Text="1" FontFamily="Arial" FontSize="9"></TextBlock> <TextBlock Name="secondLine" Text="2" FontFamily="Arial" FontSize="9"></TextBlock> <TextBlock Name="thirdLine" Text="3" FontFamily="Arial" FontSize="9"></TextBlock> </StackPanel> </Grid> </UserControl> Its code: public sealed partial class CircularGraph: UserControl { public CircularGraph() { this.InitializeComponent(); Height = 300; Width = 400; } public void changeFirstLine(string var) { firstLine.Text = var; } } In other page I put: <local:CircularGraph Name="circularGraph"/> And I've tried to put this in .cs: protected override void OnNavigatedTo(NavigationEventArgs e) { circularGraph.changeFirstLine("aaa"); } But I have an error: The name 'circularGraph' does not exits in the current context. How can I do this? Sorry if it's a simple question. I'm newbie at Windows phone. Thank you very much!
Try x:Name instead of Name. "All x:Name means to XAML is generate a field to store the value in the code behind class." <local:CircularGraph x:Name="circularGraph"/> In WPF, what are the differences between the x:Name and Name attributes?
Binding to UserControl DependencyProperty does not work as expected
I have a header in each page of my Windows Phone 8 Silverlight app. To stop repeating myself I decided to create a simple UserControl witch holds a Grid and a TextBlock. The text of the TextBlock is binded to a DependencyProperty of the UserControl (TitleProperty). See the code at the end. For the binding to the TitleProperty to work properly I needed to bind the DataContext of the UserControl to itself with the code: DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}". This works properly when using the control in a page and setting a fixed value or a StaticBinding for the Title property. Ex.: This works: <uiuc:SubSectionHeader Title="My fixed title" /> This works to <uiuc:SubSectionHeader Title="{Binding Source={StaticResource Literals}, Path=Literals.applicationSettings, FallbackValue='[Application Settings]'}" /> But when doing a normal bind it does not work. Ex <uiuc:SubSectionHeader Title="{Binding Path=UserName'}" /> And that is because the UserControl is looking for the UserName property in its own DataContext (witch is itself), and not in the DataContext of the page. Question 1 is: Should´t it resolve the binding before passing the value to the Title property? Question 2: Is it just overwriting the binding in inside the UserControl? Question 3: How to resolve it? Please don't say create a custom control instead because it sucks <UserControl x:Class="UI.UserControls.SubSectionHeader" 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" xmlns:converters="clr-namespace:UI.Converters" mc:Ignorable="d" FontFamily="{StaticResource PhoneFontFamilyNormal}" FontSize="{StaticResource PhoneFontSizeNormal}" Foreground="{StaticResource PhoneForegroundBrush}" d:DesignHeight="50" d:DesignWidth="480" DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"> <UserControl.Resources> <converters:StringCaseConverter x:Name="ToUppercase" /> <converters:BooleanToVisibilityConverter x:Key="BoolToVisibility" /> </UserControl.Resources> <Grid x:Name="LayoutRoot" Height="50" Background="{Binding Source={StaticResource ThemeSetter}, Path=BackgroundColor}"> <TextBlock VerticalAlignment="Center" Margin="25 0 0 0" Style="{StaticResource PhoneTextNormalStyle}" Foreground="White" Text="{Binding Path=Title, Mode=TwoWay, Converter={StaticResource ToUppercase}, ConverterParameter='upper', FallbackValue='[SUB SECTION TITLE]'}" /> </Grid> </UserControl> Code behind: using System.Windows; using System.Windows.Controls; namespace UI.UserControls { public partial class SubSectionHeader : UserControl { public SubSectionHeader() { InitializeComponent(); } public string Title { get { return (string)GetValue( TitleProperty ); } set { SetValue( TitleProperty, value ); } } public static readonly DependencyProperty TitleProperty = DependencyProperty.Register( "Title", typeof( string ), typeof( SubSectionHeader ), new PropertyMetadata( "[SubSection Title]" ) ); } }
Have you tried setting the DataContext of your UserControl in the code behind? (You would remove the setter in the xaml) public partial class SubSectionHeader : UserControl { public SubSectionHeader() { InitializeComponent(); DataContext = this; } Edit: Try setting the design instance of your control inside the xaml. (Leave the code behind statement as well) <UserControl x:Class="MyControl 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" d:DesignHeight="300" d:DesignWidth="400" d:DataContext="{d:DesignInstance}">
Windows Phone 7 XAML -- getting a binding to work with the container of my object
What I want to do is bind the text of a TextBlock to my custom ButtonSymbol property of the UserControl. Here is the XAML for the UserControl. The Binding part for the TextBlock needs to be filled in. <UserControl 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" x:Class="Calculator.CalculatorButton" d:DesignWidth="120" d:DesignHeight="80"> <Grid x:Name="LayoutRoot" Background="Transparent"> <Image Source="buttonb#2x.png" Stretch="Fill"/> <Button x:Name="InvisibleButton" Content="{Binding ButtonSymbol}" Margin="0,0,0,0" d:LayoutOverrides="Width, Height" BorderThickness="1" Click="InvisibleButton_Click"/> <TextBlock HorizontalAlignment="Center" Margin="0,0,0,0" TextWrapping="Wrap" Text="{Binding ????????}" VerticalAlignment="Top"/> </Grid> </UserControl> And here is the CodeBehind: namespace Calculator { public partial class CalculatorButton : UserControl { public string ButtonSymbol {get; set;} public CalculatorButton() { // Required to initialize variables InitializeComponent(); } private void Button_Click(object sender, System.Windows.RoutedEventArgs e) { // TODO: Add event handler implementation here. } private void InvisibleButton_Click(object sender, System.Windows.RoutedEventArgs e) { Debug.WriteLine(#"click"); Debug.WriteLine(ButtonSymbol); // TODO: Add event handler implementation here. } } } Note that this is WP7 with Silverlight, and the RelativeSource class is not the same as in other versions.
You need to set the DataContext of the user control. If you add this: this.DataContext = this; into the constructor or Loaded event of the user control you can then do this: Text="{Binding ButtonSymbol}" Note that you can also declaratively bind the DataSource of the XAML, this is just an easy programmatic way to do it.