WPF UserControl绑定问题

时间:2011-07-01 12:09:10

标签: c# wpf

我喜欢用自己的标题属性创建一个UserControl。

public partial class SomeClass: UserControl, INotifyPropertyChanged
{
    public SomeClass()
    {
        InitializeComponent();
    }

    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;
}

在UserContol xaml中:

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

如果我设置的值:AA2P.Header = "SomeHeeaderText";,则label.Caption不会更改。我该如何解决这个问题?

在Windows xaml中:

uc:SomeClass x:Name="AA2P" 

如果我直接给一个值标记(lbHeader.Content = header;)而不是OnPropertyChanged("Header");,但为什么它不适用于OnPropertyChanged


我需要使用DataContext来实现其他目的。我尝试使用依赖属性但是出了点问题。

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>

它不起作用。我做错了什么? 谢谢!

3 个答案:

答案 0 :(得分:4)

最简单的方法是只对对象的DataContext。一种方法是直接在构造函数中这样做:

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

设置DataContext将指定应从哪里获取新数据。在文章WPF Basic Data Binding FAQ中有一些很棒的提示和信息。阅读它以更好地了解DataContex可用于什么。它是WPF / C#中的重要组成部分。


由于更新问题而更新。

根据我的理解,您应该将DependencyProperty.Register的第一个参数更改为要绑定到的属性的名称,此处为"Header"以及类的类型的第二个参数,这里SomeClass。这会让你:

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

但是我很少使用依赖属性,所以我不肯定这就是它,但值得一试......

答案 1 :(得分:1)

如果您需要其他内容的数据上下文。您还可以在Binding中使用ElementName属性。

    <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>

[编辑]

我应该添加一些东西。使“Header”属性成为依赖属性,这将使您的生活变得更加轻松。在UI控件中,您应该使属性几乎总是依赖属性,控件的每个设计者或用户都会感谢您。

答案 2 :(得分:1)

UserControl本身需要稍后使用它的DataContext。但UserControl中的控件需要UserControl作为其DataContext,否则它们也将从后来的使用上下文继承DataContext。诀窍是将UserControl的子项的DataContext设置为UserControl的子项,因此它现在可以使用UserControl的依赖项属性。

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

如果你这样做,Grid的子节点可以有简单的{Binding dp的名字},而不需要额外的ElementName参数。