通过另一个依赖项属性将变量绑定到依赖项属性

时间:2012-08-31 16:16:31

标签: c# .net wpf data-binding dependency-properties

我有以下控件嵌入(不是继承,只是放置): enter image description here

Native TextBlock放在MyMiddleControl中,MyMiddleControl放在MyGlobalControl中。 MyMiddleControl有一个DependencyPropery“GroupName”,绑定到TextBox.Text。 MyGlobalControl有一个公共属性“MyText,绑定到MyMiddleControl.GroupName。

XAML:

<UserControl x:Class="MyMiddleControl"
         ...
         DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
    <TextBlock Text="{Binding Path=GroupName}"/>
</UserControl>

public static readonly DependencyProperty GroupNameProperty =
    DependencyProperty.Register("GroupName", typeof(string), 
    typeof(MyMiddleControl), 
    new PropertyMetadata("default"));

public string GroupName
{
    get { return (string)GetValue(GroupNameProperty); }
    set { SetValue(GroupNameProperty, value); }
}

<UserControl x:Class="MyGlobalControl"
         ...
         DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
    <MyMiddleControl GroupName="{Binding MyText}"... />
</UserControl>

public string _myText = "myDef";
public string MyText
{
    get { return _myText ; }
    set { _myText = value; }
}
问题#1。当我运行程序时,我在文本块中看到“default”而不是“myDef”。

问题#2。我有按钮:

private void TestButton_Click(object sender, RoutedEventArgs e)
{
    MyText = "TestClick";
}

结果相同:“默认”。

为什么呢? :(

更新:

我忘了说。如果我做

<UserControl x:Class="MyGlobalControl"
         ...
         DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}">
    <MyMiddleControl GroupName="FixedTest"... />
</UserControl>

工作正常。

PS。示例项目的第一个答案发生了变化:TestBind.zip

1 个答案:

答案 0 :(得分:2)

您必须实现INotifyPropertyChanged以通知绑定属性的更改

public class SampleData : INotifyPropertyChanged
{
  public SampleData ()
  {
     this.MyText = "myDef";
  }

  public string _myText;
  public string MyText
  {
    get { return _myText ; }
    set {
      _myText = value;
      this.RaisePropChanged("MyText");
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;

  public void RaisePropChanged(string name) {
    var eh = this.PropertyChanged;
    if (eh != null) {
      eh(this, new PropertyChangedEventArgs(name));
    }
  }
}

希望有所帮助

修改 尝试使用设置x:名称和DataContext代码

后面的解决方案
public partial class MyMiddleControl : UserControl
{
  public MyMiddleControl() {
    this.DataContext = this;
    this.InitializeComponent();
  }

  public static readonly DependencyProperty GroupNameProperty =
    DependencyProperty.Register("GroupName", typeof(string),
                                typeof(MyMiddleControl),
                                new PropertyMetadata("default"));

  public string GroupName {
    get { return (string)this.GetValue(GroupNameProperty); }
    set { this.SetValue(GroupNameProperty, value); }
  }
}

<UserControl x:Class="TestBind.MyMiddleControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Name="middleControl">
    <Grid>
        <TextBlock Height="40" HorizontalAlignment="Left" Margin="45,23,0,0" 
                   Name="textBlock1" Text="{Binding ElementName=middleControl, Path=GroupName}" 
                   VerticalAlignment="Top" Width="203" />
    </Grid>
</UserControl>

public partial class MyGlobalControl : UserControl, INotifyPropertyChanged
{
  public MyGlobalControl() {
    this.DataContext = this;
    this.InitializeComponent();
    this.MyText = "myDef";
  }

  public string _myText;
  public string MyText {
    get { return this._myText; }
    set {
      this._myText = value;
      this.OnPropertyChanged("MyText");
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;

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

  private void button1_Click(object sender, RoutedEventArgs e) {
    this.MyText = "btnClick";
  }
}

<UserControl x:Class="TestBind.MyGlobalControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:my="clr-namespace:TestBind"
             x:Name="globalControl">
  <Grid>
    <my:MyMiddleControl HorizontalAlignment="Left"
                        Margin="24,82,0,0"
                        x:Name="myFloatTest"
                        GroupName="{Binding ElementName=globalControl, Path=MyText}"
                        VerticalAlignment="Top" />
    <Button Content="Button"
            Height="23"
            HorizontalAlignment="Left"
            Margin="296,65,0,0"
            Name="button1"
            VerticalAlignment="Top"
            Width="75"
            Click="button1_Click" />
  </Grid>
</UserControl>