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

WPF DataBinding Not working - creation of DataTemplate using code

我在 xaml 代码中创建了一个名为 ValueTreeView 的树视图,它使用在以下代码中创建的数据模板,它完全绑定到通用 class ValueHolder

这是用于绑定的class

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 变量。

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

事件处理程序更改了 class 的 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>

ObservableCollection 仅适用于集合更改,不适用于集合中项目的更改。您需要为 ValueHolder class 实现 INotifyPropertyChanged 接口 更多详情 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));
          }
      }
  }
}