【问题标题】:Dictionary - TextBox binding is not working字典 - 文本框绑定不起作用
【发布时间】:2017-01-13 09:16:18
【问题描述】:

我没有使用视图模型,有一篇类似的帖子使用了视图模型,我尝试以此为基础,但它不起作用, WPF binding textbox to dictionary entry

当我点击我的按钮时,我创建了一个列表,然后形成了一个字典,所以在我的精简示例中,为了让它工作,我在按钮单击时创建字典

代码隐藏

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }
private Dictionary<string, string> _MyDict;


    public Dictionary<string, string> MyDict        {
        get { return _MyDict; }
        set { _MyDict= value; }
    }
 private void button_Click(object sender, RoutedEventArgs e)
    {
      MyDict = new Dictionary<string, string>
       { 
          {"First", "Test1"},
          {"Second", "Test2"}
       };
    }
  }

XAML

Title="MainWindow" Height="350" Width="674.167">
<Grid>
    <Button x:Name="createListfromTextFile" Content="hi" Click="button_Click"/>

    <TextBox x:Name="textBox1"  Text="{Binding MyDict[First], UpdateSourceTrigger=PropertyChanged}" Height="279" >

</Grid>

更新

根据 Chrille 的评论,我解决了这个问题, 通过像这样实现INotifyPropertyChanged

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

 public Dictionary<string, string> MyDict
    {
        get { return _MyDict; }
        set {

            _MyDict = value;
            if (null != PropertyChanged)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs  ("MyDict"));
            }
        }          
     }
  }

【问题讨论】:

  • 您基本上使用的是视图模型,即您的 MainWindow 类(DataContext)。视图模型类需要实现 INotifyPropertyChanged 以通知 UI 有关更改。
  • @Chrille,是的,你是对的......那行得通,谢谢 - 对不起,我是这个东西的新手
  • @JohnChris 您应该写一个答案并将其标记为已接受,而不是编辑问题。
  • @Clemens,好吧,酷,我改了——希望 Chrille 会发布一个答案,这样我就可以将其标记为接受,但他从来没有这样做过 :(
  • 如果我需要通过一个键索引到集合中,我要么只使用常规的 ObservableCollection 和 FirstOrDefault 它(实际上,它几乎总是足够快),或者我创建一个扩展 KeyedCollection 和实现 INotifyCollectionChanged。 KC 是一个 IEnumerable ,其中 T 可以是你想要的任何东西,它与 DataTemplates 配合得很好。字典都是 IEnumerable>,所以你不能轻易利用自动数据模板选择。

标签: c# wpf mvvm inotifypropertychanged


【解决方案1】:

您的 MainWindow 类 (DataContext) 需要实现 INotifyPropertyChanged。

public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    public Dictionary<string, string> MyDict
    {
        get { return _MyDict; }
        set 
        {
            _MyDict = value;
            PropertyChanged?.(this, new PropertyChangedEventArgs("MyDict"));
        }         
    }
}

或者更好的是,为视图模型创建一个单独的类并从 ViewModelBase 或类似继承:

public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void NotifyPropertyChanged(params string[] propertyName)
        {
            foreach (var prop in propertyName)
            {
                OnPropertyChanged(new PropertyChangedEventArgs(prop));
            }
        }

        protected virtual void OnPropertyChanged(PropertyChangedEventArgs args)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged.Invoke(this, args);
            }
        }
    }

最后在 setter 中:

public Dictionary<string, string> MyDict
{
    get { return _MyDict; }
    set 
    {
        _MyDict = value;
        NotifyPropertyChanged("MyDict");
    }         
}

【讨论】:

    【解决方案2】:

    根据 Chrille 的评论,我通过像这样实现 INotifyPropertyChanged 解决了这个问题:

     public partial class MainWindow : Window, INotifyPropertyChanged
     {
        public MainWindow()
       {
        InitializeComponent();
        this.DataContext = this;
       }
    
     public Dictionary<string, string> MyDict
     {
        get { return _MyDict; }
        set {
    
            _MyDict = value;
            if (null != PropertyChanged)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs  ("MyDict"));
            }
        }          
     }
    }
    

    感谢您的帮助!

    【讨论】:

      【解决方案3】:

      我在您的代码中发现的主要原因是,您忘记实现接口,如果您以正确的方式实现它们意味着您的代码将正常工作。请尝试以下操作:

      public partial class MainWindow : Window, INotifyPropertyChanged
      {
      
          // include your code here
      
          // change the property definition as like this:
         public Dictionary<string, string> MyDict       
         {
             get { return _MyDict; }
             set 
             {
                _MyDict= value; 
                NotifyPropertyChanged("MyDict");  
             }
         }
      
          // interface implementation
          public event PropertyChangedEventHandler PropertyChanged;
      
          private void NotifyPropertyChanged(string propertyName = "")
          {
              if (PropertyChanged != null)
              {
                  PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-08-12
        • 2016-08-28
        • 2012-02-10
        • 1970-01-01
        • 2011-10-15
        • 1970-01-01
        • 1970-01-01
        • 2013-07-13
        • 1970-01-01
        相关资源
        最近更新 更多