WPF DataBinding不起作用 - 使用代码创建DataTemplate

时间:2015-01-06 07:06:12

标签: c# wpf xaml data-binding treeview

我在xaml代码中创建了一个名为ValueTreeView的treeView,它使用在以下代码中创建的datatemplate,它完全绑定到泛型类ValueHolder

这是用于绑定的类

public class ValueHolder
{
    public string VHName{ get; set; }
    public string VHValue{ get; set; }
}

这是具有树视图的用户控件

  public partial class UserControl1 : UserControl
  {
     ObservableCollection<ValueHolder> source;

     public UserControl1()
     {

        InitializeComponent();

        source= new ObservableCollection<ValueHolder>();

        //Data Template for the treeView

        DataTemplate cardLayout = new DataTemplate();
        cardLayout.DataType = typeof(ValueHolder);

        FrameworkElementFactory ValueStack= new FrameworkElementFactory(typeof(StackPanel));
        ValueStack.Name = "Details";
        ValueStack.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

        FrameworkElementFactory VName= new FrameworkElementFactory(typeof(TextBlock));
        VName.SetBinding(TextBlock.TextProperty, new Binding("VHName"));
        ValueStack.AppendChild(VName);

        FrameworkElementFactory Space = new FrameworkElementFactory(typeof(TextBlock));
        Space.SetValue(TextBlock.WidthProperty, 10.0);
        ValueStack.AppendChild(Space);

        FrameworkElementFactory VValue= new FrameworkElementFactory(typeof(TextBlock));
        VValue.SetBinding(TextBlock.TextProperty, new Binding("VHValue"));
        ValueStack.AppendChild(VValue);

        cardLayout.VisualTree = ValueStack;

        ValueTreeView.ItemTemplate = cardLayout;

        //Initializing the TreeViewItems

        ValueHolder vh1 = new ValueHolder() { VHName = "VH1", VHValue = "456"};
        ValueHolder vh2 = new ValueHolder() { VHName = "VH2", VHValue = "578"};
        ValueHolder vh3 = new ValueHolder() { VHName = "VH3", VHValue = "235"};

        source.Add(vh1);
        source.Add(vh2);
        source.Add(vh3);

        ValueTreeView.ItemsSource = source;

    }

以下是选择项目更改时调用的事件处理程序

    private void ValueTreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
    { 
        var s=((ValueHolder)((TreeView)sender).SelectedItem);
        if(s.VHName=="VH2")
            s.VHValue = "111";
    }
}

每个TreeViewItem中的两个文本块绑定到两个类变量。

我的问题是当我更改Class属性的值时,它不会反映在UI中,即使我使用ObservableCollection作为TreeView的Item源。

事件处理程序更改了类的VHValue属性,它在后端发生了变化,但未反映在UI中

我的xaml代码:

   <UserControl x:Class="Checker.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
  <Grid>
  <TreeView x:Name="ValueTreeView" SelectedItemChanged="ValueTreeView_SelectedItemChanged">           
  </TreeView>
  </Grid>
  </UserControl>

1 个答案:

答案 0 :(得分:1)

ObservableCollection仅适用于集合更改,而不适用于集合中项目的更改。您需要为INotifyPropertyChanged类实现ValueHolder接口 更多详情here

  public class ValueHolder : INotifyPropertyChanged
  {
      private string _VHName;
      private string _VHValue;
      // Declare the event 
      public event PropertyChangedEventHandler PropertyChanged;

      public string VHName
      {
          get { return _VHName; }
          set
          {
              _VHName = value;
              // Call OnPropertyChanged whenever the property is updated
              OnPropertyChanged("VHName");
          }
      }

      public string VHValue
      {
          get { return _VHValue; }
          set
          {
              _VHValue= value;
              // Call OnPropertyChanged whenever the property is updated
              OnPropertyChanged("VHValue");
          }
      }

      // Create the OnPropertyChanged method to raise the event 
      protected void OnPropertyChanged(string name)
      {
          PropertyChangedEventHandler handler = PropertyChanged;
          if (handler != null)
          {
              handler(this, new PropertyChangedEventArgs(name));
          }
      }
  }
}