locked
User Control Custom Properties RRS feed

  • Question

  • Hello,

    I am using Blend 3, and i created a user control.

    This user control has labels, and I want to bind from a sample data to a label on this user control.

    I found something about DependencyProperty but I am not realy sure how to use it and how to get it to affect on the label.

    Thanks in avdvanc for your help.

    Sunday, October 24, 2010 8:59 PM

Answers

  • OK, dependency property is what you want then.

     

    Here is a bit of good info:

    http://blog.kirupa.com/?p=331

     

    Here is an example that I believe does what you wanted:

    public partial class UserControl1 : UserControl
    	{
    		public UserControl1()
    		{
    			this.InitializeComponent();
    		}
    
    
    		public string LabelText
    		{
    			get
    			{
    				return this.GetValue(LabelTextProperty) as string;
    			}
    			set
    			{
    				this.SetValue(LabelTextProperty, value);
    			}
    		}
    
    		public static readonly DependencyProperty LabelTextProperty = DependencyProperty.Register("LabelText", typeof(string),
    																								 typeof(UserControl1),
    																								 new PropertyMetadata(new PropertyChangedCallback(OnLabelTextChanged)));
    
    		private static void OnLabelTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    		{
    			var uc1 = d as UserControl1;
    			if (uc1 != null)
    			{
    				uc1.Label.Content = e.NewValue;
    			}
    		}
    	}
    
    <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="WpfApplication16.UserControl1"
    	x:Name="UserControl"
    	d:DesignWidth="640" d:DesignHeight="480">
    
    	<Grid x:Name="LayoutRoot">
    		<Label x:Name="Label" Content="Label" HorizontalAlignment="Left" Height="59" Margin="52,43,0,0" VerticalAlignment="Top" Width="182"/>
    	</Grid>
    </UserControl>
    
    <Window
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:local="clr-namespace:WpfApplication16"
    	x:Class="WpfApplication16.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480">
    	<Window.Resources>
    		<DataTemplate x:Key="ItemTemplate">
    			<StackPanel>
    				<TextBlock Text="{Binding Property1}"/>
    				<CheckBox IsChecked="{Binding Property2}"/>
    			</StackPanel>
    		</DataTemplate>
    	</Window.Resources>
    
    	<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource SampleDataSource}}">
    		<local:UserControl1 Margin="18,18,217,162" LabelText="{Binding Collection[0].Property1}"/>
    		<ListBox HorizontalAlignment="Right" ItemTemplate="{DynamicResource ItemTemplate}" ItemsSource="{Binding Collection}" Margin="0,34,13,108" Width="200"/>
    	</Grid>
    </Window>
    

    • Proposed as answer by Chuck HaysModerator Monday, October 25, 2010 2:19 PM
    • Marked as answer by ori123 Monday, October 25, 2010 7:59 PM
    Monday, October 25, 2010 2:19 PM
    Moderator

All replies

  • Can you describe what you are trying to do in more detail?
    Monday, October 25, 2010 1:26 PM
    Moderator
  • I have a usercontrol, "UC", and it has a label "Label".

    When I put this UC in some Project, I want the Project to be able to change the label's content.

    I tried to do this in the code behind:

     

    Public string text
    
    {
    
    	get {return this.Label.Content.ToString();}
    
    	set {This.Label.Content=value;}
    
    }
    

     

    But when I tried to insert a value, I couldnt Bind a value from a sample data, I could only insert a regular value like "Bla".

    Monday, October 25, 2010 1:57 PM
  • OK, dependency property is what you want then.

     

    Here is a bit of good info:

    http://blog.kirupa.com/?p=331

     

    Here is an example that I believe does what you wanted:

    public partial class UserControl1 : UserControl
    	{
    		public UserControl1()
    		{
    			this.InitializeComponent();
    		}
    
    
    		public string LabelText
    		{
    			get
    			{
    				return this.GetValue(LabelTextProperty) as string;
    			}
    			set
    			{
    				this.SetValue(LabelTextProperty, value);
    			}
    		}
    
    		public static readonly DependencyProperty LabelTextProperty = DependencyProperty.Register("LabelText", typeof(string),
    																								 typeof(UserControl1),
    																								 new PropertyMetadata(new PropertyChangedCallback(OnLabelTextChanged)));
    
    		private static void OnLabelTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    		{
    			var uc1 = d as UserControl1;
    			if (uc1 != null)
    			{
    				uc1.Label.Content = e.NewValue;
    			}
    		}
    	}
    
    <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="WpfApplication16.UserControl1"
    	x:Name="UserControl"
    	d:DesignWidth="640" d:DesignHeight="480">
    
    	<Grid x:Name="LayoutRoot">
    		<Label x:Name="Label" Content="Label" HorizontalAlignment="Left" Height="59" Margin="52,43,0,0" VerticalAlignment="Top" Width="182"/>
    	</Grid>
    </UserControl>
    
    <Window
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    	xmlns:local="clr-namespace:WpfApplication16"
    	x:Class="WpfApplication16.MainWindow"
    	x:Name="Window"
    	Title="MainWindow"
    	Width="640" Height="480">
    	<Window.Resources>
    		<DataTemplate x:Key="ItemTemplate">
    			<StackPanel>
    				<TextBlock Text="{Binding Property1}"/>
    				<CheckBox IsChecked="{Binding Property2}"/>
    			</StackPanel>
    		</DataTemplate>
    	</Window.Resources>
    
    	<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource SampleDataSource}}">
    		<local:UserControl1 Margin="18,18,217,162" LabelText="{Binding Collection[0].Property1}"/>
    		<ListBox HorizontalAlignment="Right" ItemTemplate="{DynamicResource ItemTemplate}" ItemsSource="{Binding Collection}" Margin="0,34,13,108" Width="200"/>
    	</Grid>
    </Window>
    

    • Proposed as answer by Chuck HaysModerator Monday, October 25, 2010 2:19 PM
    • Marked as answer by ori123 Monday, October 25, 2010 7:59 PM
    Monday, October 25, 2010 2:19 PM
    Moderator
  • Thanks! It worked!
    • Edited by ori123 Monday, October 25, 2010 7:59 PM
    Monday, October 25, 2010 7:44 PM
  • Could you post the relevant code you are using?
    Monday, October 25, 2010 7:47 PM
    Moderator
  • It is just like yours, but in C#...
    Tuesday, October 26, 2010 8:33 PM