【问题标题】:WPF C# binding code - why doesn't this simple example work?WPF C# 绑定代码 - 为什么这个简单的示例不起作用?
【发布时间】:2011-04-09 13:29:05
【问题描述】:

我附上了一些 WPF C# 绑定代码 - 为什么这个简单的示例不起作用? (只是试图理解绑定到自定义对象)。也就是在模型中点击按钮增加计数器时,标签没有更新。

<Window x:Class="testapp1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button  Height="23" HorizontalAlignment="Left" Margin="20,12,0,0" 
                 Name="testButton" VerticalAlignment="Top" Width="126" 
                 Click="testButton_Click" Content="Increase Counter" />
        <Label Content="{Binding Path=TestCounter}" Height="37" 
               HorizontalAlignment="Right" Margin="0,12,122,0" 
               Name="testLabel2" VerticalAlignment="Top" 
               BorderThickness="3" MinWidth="200"  />
    </Grid>
</Window>


namespace testapp1
{
    public partial class MainWindow : Window
    {
        public TestModel _model;

        public MainWindow()
        {
            InitializeComponent();

            InitializeComponent();
            _model = new TestModel();
            _model.TestCounter = 0;
            this.DataContext = _model;
        }

        private void testButton_Click(object sender, RoutedEventArgs e)
        {
            _model.TestCounter = _model.TestCounter + 1;
            Debug.WriteLine("TestCounter = " + _model.TestCounter);
        }
    }

    public class TestModel : DependencyObject
    {
        public int TestCounter { get; set; }
    }

}

谢谢

【问题讨论】:

    标签: c# .net wpf binding


    【解决方案1】:

    对于这个简单的示例,请考虑使用 INotifyPropertyChanged 而不是 DependencyProperties!

    更新 如果你确实想使用 DP,请使用 VS2010 中的 propdp sn-p 或Dr WPF's snippets for VS2008?

    【讨论】:

      【解决方案2】:

      TestCounter 需要是 DependencyProperty

          public int TestCounter
          {
              get { return (int)GetValue(TestCounterProperty); }
              set { SetValue(TestCounterProperty, value); }
          }
      
          // Using a DependencyProperty as the backing store for TestCounter.  
          //This enables animation, styling, binding, etc...
          public static readonly DependencyProperty TestCounterProperty =
              DependencyProperty.Register
                   ("TestCounter", 
                    typeof(int), 
                    typeof(TestModel), 
                    new UIPropertyMetadata(0));
      

      【讨论】:

      • 谢谢 - 现在就尝试一下 - 所以你永远不能真正直接绑定到 WPF 中的普通旧类对象?
      • 如果你实现了 INotifyPropertyChanged 就可以了
      • 不,一点也不——您可以绑定到任何 POCO 对象的任何属性,只要您通知目标(例如您的文本框上的 TextProperty)任何更改。 DependenyProperties 为您完成这项工作,但您也可以在 TestModel 类上实现 INotifyPropertyChanged(根据@rudigrobler 的建议)并手动引发更改事件...
      • @Daniel - 在 TestModel 类中添加了以下内容,但它仍然不起作用? "public static readonly DependencyProperty TestCounterProperty = DependencyProperty.Register("TestCounter", typeof(int), typeof(TestModel), new UIPropertyMetadata(0));"
      • 挂起 - 我错过了对 TestCounter 类的更改
      【解决方案3】:

      您可以在 System.ComponentModel 命名空间中实现 INotifyPropertyChanged 接口。我通常实现一个 Changed 方法,该方法可以获取多个属性名称并检查未设置的事件。我这样做是因为有时我有多个依赖于一个值的属性,我可以从我的所有属性设置器中调用一种方法。

      例如,如果您有一个具有 Width 和 Height 属性的 Rectangle 类以及一个返回 Width * Height 的 Area 只读属性,您可以将 Changed("Width", "Area");在 Width 的属性设置器中。

      public class TestModel : INotifyPropertyChanged
      {
          int m_TestCounter;
          public int TestCounter {
              get {
                  return m_TestCounter;
              }
              set {
                  m_TestCounter = value;
                  Changed("TestCounter");
              }
          }
      
          #region INotifyPropertyChanged Members
      
          public event PropertyChangedEventHandler PropertyChanged;
      
          #endregion
      
          void Changed(params string[] propertyNames)
          {
              if (PropertyChanged != null)
              {
                  foreach (string propertyName in propertyNames)
                  {
                      PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                  }
              }
          }
      }
      

      【讨论】:

      • Jason - 只是想了解这个建议如何适用于我遇到的问题?您将如何在这里使用这个概念?
      • 当您的对象绑定到控件时,该控件会将自己添加为来自 INotifyPropertyChanged 接口的 PropertyChanged 事件的侦听器。当您在属性设置器中触发该事件时,绑定到该属性的控件会在 UI 中更新。每当调用 TestCounter 设置器时,上面的代码将自动更新 UI。您确实需要在属性后面有一个变量并在您的设置器中调用 Changed 方法,但对我来说这比使用 DependencyProperty 更容易。
      猜你喜欢
      • 1970-01-01
      • 2017-11-25
      • 2013-03-16
      • 1970-01-01
      • 2013-05-04
      • 2012-05-25
      • 1970-01-01
      • 1970-01-01
      • 2011-01-15
      相关资源
      最近更新 更多