WPF:检测Datagrid的更改

时间:2018-11-05 20:16:09

标签: c# wpf mvvm

我有一个数据网格

<DataGrid ItemsSource="{Binding MyList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
  <DataGrid.Columns>
    <DataGridTextColumn Header="Name"
                                Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
  </DataGrid.Columns>
</DataGrid>

是来源

    /*** Added constructor ***/
    public SetupVM()
    {
        ConnectionString = Path.Combine(DATABASE_PATH, DATABASE_NAME);
        MyList = new List<MyObjectINotifyImplemented>();

        /* MyList= new ObservableCollection<MyObjectINotifyImplemented>(); */

        if (!File.Exists(ConnectionString))
        {
            FirstRun();
        }
    }

    public void FirstRun()
    {
        BoilerPlate boilerPlate = new BoilerPlate();
        Directory.CreateDirectory(DATABASE_PATH + "\\databaseFile");

        using (SQLiteConnection conn = new SQLiteConnection(ConnectionString))
        {
            conn.CreateTable<MyObjectINotifyImplemented>();

            foreach (seed in MyObjectINotifyImplemented.seeds)
            {
                var t = conn.Insert(seed);
            }
        }
    }

    private List<MyObjectINotifyImplemented> _mylist;

    public List<MyObjectINotifyImplemented> MyList
    {
        get { return _mylist; }
        set
        {
            _mylist= value;
            /****  Called on initialization in ctor and never again ****/
            MyMethodThatShouldBeCalled();
        }
    }

模型样本:

class MyObjectINotifyImplemented : INotifyPropertyChanged
{
  [PrimaryKey, AutoIncrement]
  public int Id { get; set; }
  private string _name;

  public string Name
  {
    get { return _name; }
    set
    {
      _name = value;
      OnPropertyChanged("Name");
    }
  }

  /** Generated by VS **/
  public event PropertyChangedEventHandler PropertyChanged;

  [NotifyPropertyChangedInvocator]
  protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
  {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

我一遍又一遍地看到这个问题,但是我正在实现我能找到的一切?

大多数问题通过绑定模式或添加UpdateSourceTrigger = PropertyChanged解决。

可能缺少什么?忽略错别字,我只是手工切掉了相关部分。

3 个答案:

答案 0 :(得分:0)

MyList的定义从List<MyObjectINotifyImplemented>更改为ObservableCollection<MyObjectINotifyImplemented>,这是您要在构造函数中更新的内容。

答案 1 :(得分:0)

很抱歉,您对这个问题持否定态度,但只能打一次电话。那是您实际加载列表的唯一位置。除非表单上有其他东西会强制刷新并重新查询您的数据(例如从您的连接字符串/数据库中),否则它不会。你只有

  1. 准备一个空列表(应该是ObservableCollection)
  2. 定义您的数据网格(但仍然没有任何指示实际设置了DataContext的形式)
  3. 您没有基于connectionString设置的文件,您调用FirstRun,但不显示FirstRun的功能。
  4. 如果预期的文件确实存在,则不会显示您查询要填充的任何内容。

您提供了各种部分实现,但显然不足以使其余功能得到实现。

答案 2 :(得分:0)

  

大多数问题都是通过绑定模式或添加UpdateSourceTrigger=PropertyChanged来解决的。

仅当控件实际上可以实际设置source属性时,设置UpdateSourceTriggerMode属性才有意义。 DataGrid不会设置ItemsSource属性的来源,因此在这种情况下设置这些属性毫无意义。

DataGrid将永远不会调用MyList源属性的设置器。只有getter会被调用。这是预期的行为。您应该这样定义绑定:

<DataGrid ItemsSource="{Binding MyList}">

例如,如果您绑定Text的{​​{1}}属性,则指定TextBoxUpdateSourceTrigger来控制{{ 1}}设置source属性。但是在绑定Mode的{​​{1}}属性时却没有。

目前尚不清楚您为什么期望或希望在此框架中调用源集合属性的设置方法,因为这是不应该的。而且不会。

如果要检测从TextBox添加或删除的项目,应将ItemsSource替换为ItemsControl并处理源集合的DataGrid事件。该集合本身不会被替换。