开发者

WPF UserControl Binding Problem

开发者 https://www.devze.com 2023-03-16 13:37 出处:网络
I like to create a UserControl with own Header Property. public partial class SomeClass: UserControl, INotifyPropertyChanged

I like to create a UserControl with own Header Property.

public partial class SomeClass: UserControl, INotifyPropertyChanged
{
    public SomeClass()
    {
        InitializeCompon开发者_JS百科ent();
    }

    private string header;
    public string Header
    {
        get { return header; }
        set 
        { 
            header = value;
            OnPropertyChanged("Header");
        }
    }

    protected void OnPropertyChanged(string propertyName)                    
    {                                                                        
        if (this.PropertyChanged != null)                                    
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

in UserContol xaml:

Label Name="lbHeader" Grid.Column="0" Content="{Binding Path=Header}"

If I set the value: AA2P.Header = "SomeHeeaderText"; than the label.Caption will not changed. How can I solve that problem?

In Windows xaml:

uc:SomeClass x:Name="AA2P" 

If I give directly a value to label (lbHeader.Content = header;) instead of OnPropertyChanged("Header"); its work but, why it does not work with OnPropertyChanged?


I need to use DataContext for somethig else. I try to use dependency property but something is wrong.

public partial class tester : UserControl
{
    public tester()
    {
        InitializeComponent();
    }

    public string Header
    {
        get { return (string)GetValue(MyDependencyProperty); }
        set { SetValue(MyDependencyProperty, value); }
    }
    public static readonly DependencyProperty MyDependencyProperty =
    DependencyProperty.Register("MyDependencyProperty", typeof(string), typeof(string));

}


<UserControl ... x:Name="mainControl">
<TextBlock Text="{Binding ElementName=mainControl, Path=MyDependencyProperty}"/>
</UserControl>


<Window ...>
<my:tester Header="SomeText" />
</Window>

It does not work. What I do wrong? Thanks!


The easiest approach is to just the DataContext of your object. One way of doing that is directly in the constructor like this:

public SomeClass()
    {
        InitializeComponent();
        DataContext = this;
    }

Setting the DataContext will specify where new data should be fetched from. There are some great tips and information in the article called WPF Basic Data Binding FAQ. Read it to better understand what the DataContex can be used for. It is an essential component in WPF/C#.


Update due to update of the question.

To my understanding you should change the first argument of DependencyProperty.Register to the name of the property that you want to bind to, here "Header" as well as the second argument to the type of your class, here SomeClass. That would leave you with:

public static readonly DependencyProperty MyDependencyProperty =
    DependencyProperty.Register("Header", typeof(SomeClass), typeof(string));

But i seldom use dependency properties so I am not positive that this is it, but its worth a try..


If you need the Data context for something else. You can also utilize the ElementName property in the Binding.

    <UserControl
        x:Class="MyControl.MyUserControl"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="mainControl">
        <TextBlock Text="Binding ElementName=mainControl, Path=MyDependencyProperty}"/>
    </UserControl>

[Edit]

I should add something. Make the "Header" property a dependency property, this will make your live much easier. In UI Controls you should make property almost always a dependency property, every designer or user of your control will thank you.


The UserControl itself needs the DataContext of where it is used later. But the controls inside the UserControl need the UserControl as their DataContext, otherwise they also will inherit the DataContext from the later usage context. The trick is to set the DataContext of the UserControl's child to that of the UserControl, so it now can use the dependency properties of the UserControl.

<UserControl x:Class="MyControl.MyUserControl">
  <Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor,
      AncestorType=UserControl,AncestorLevel=1}}">...</Grid>
</UserControl>

If you do this this way the children of the Grid can have simple {Binding dp's name} without additionally ElementName parameters.

0

精彩评论

暂无评论...
验证码 换一张
取 消