【问题标题】:Data grid not update when data binding in xmalxaml 中的数据绑定时数据网格不更新
【发布时间】:2018-01-19 08:46:15
【问题描述】:

我有一个名为 TimeSheetByEmployeeModel 的模型,它使用 INotifyPropertyChanged 实现。

型号:

public class TimeSheetByEmployeeModel:INotifyPropertyChanged
{
    //public string EmpID { get; set; }
    string _EmpID;
    public string EmpID
    {
        get
        {
            return _EmpID;
        }
        set
        {
            if (_EmpID != value)
            {
                _EmpID = value;
                RaisePropertyChange("EmpID");
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChange(string prop)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(prop));

        }
    }
}

视图模型:

ObservableCollection<TimeSheetByEmployeeModel> _TimeSheetList = new ObservableCollection<TimeSheetByEmployeeModel>();
public ObservableCollection<TimeSheetByEmployeeModel> TimeSheetList
{
    get
    {
        return _TimeSheetList;
    }
    set
    {                
        _TimeSheetList = value;             
    }
}

查看代码隐藏:

public TimeSheetByEmployee()
{
    InitializeComponent();          

    this.DataContext = this;
}

查看:

<DataGrid  ItemsSource="{Binding TimeSheetList,UpdateSourceTrigger=PropertyChanged}"
           AutoGenerateColumns="False"
           CanUserAddRows="False"
           x:Name="timesheetgrid"
           HeadersVisibility="All"
           RowHeaderWidth="20">

  <DataGrid.Columns>
    <DataGridTextColumn Binding="{Binding EmpID,UpdateSourceTrigger=PropertyChanged}" 
                    Header="EmpID"
                    IsReadOnly="True"
                    Width="100"/>
  </DataGrid.Columns>  
</DataGrid>

当我单击视图中的按钮时,它会调用此方法:

private void Ok_Click(object sender, RoutedEventArgs e)
{       
    try
    {
        TimeSheetList.Clear();
        string EmployeeID = cboemployee.SelectedValue.ToString();
        TimeSheetList = TimeSheetByEmployeeDataAccessor.GetTimeSheetByEmployee_ByFromTo(dtpfrom.SelectedDate.GetValueOrDefault(), dtpto.SelectedDate.GetValueOrDefault(), EmployeeID);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }          
}

我动态更改了TimeSheetList,它应该反映在数据网格中。我使用这种结构开发了另一种形式,效果很好。但是,在这种形式中,当我更改 TimeSheetList 时,它不会更新数据网格。

我研究了什么?

首先,我在视图构造函数中将一些数据绑定到TimeSheeList,并显示在数据网格中。所以我假设将TimeSheetList 绑定到数据网格有效。

其次,我在Button Click Event中修改了一些代码:

private void Ok_Click(object sender, RoutedEventArgs e)
{       
    try
    {      
        TimeSheetList.RemoveAt(0);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }          
}

此代码完美运行,并删除了数据网格中的第一行。所以我假设 datagrid itemsource 是动态变化的。

但为什么它没有用我的原始代码更新?

更多研究,

我在按钮上添加了代码:

timesheetgrid.ItemsSource = TimeSheetList;

我知道它会起作用,而且确实如此,但通常我不会在代码隐藏中将数据绑定到数据网格,我总是在 XAML 中进行数据绑定。它总是有效,但为什么在这里不起作用?

更新

如果我在调试时将Mode=TwoWay 添加到 xaml 中数据网格中的 ItemsSource 数据绑定中:

<DataGrid  
    ItemsSource="{Binding TimeSheetList,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
    AutoGenerateColumns="False"
    CanUserAddRows="False"
    x:Name="timesheetgrid"
    HeadersVisibility="All"
    RowHeaderWidth="20">

它可以工作并且数据网格显示数据。所以我保存并重新启动调试过程,它再次停止工作。

【问题讨论】:

    标签: c# wpf data-binding datagrid


    【解决方案1】:

    这一行:

    TimeSheetList = TimeSheetByEmployeeDataAccessor.GetTimeSheetByEmployee_ByFromTo(dtpfrom.SelectedDate.GetValueOrDefault(), dtpto.SelectedDate.GetValueOrDefault(), EmployeeID);
    

    创建一个新集合,setter 中没有关于更改的通知:

    set
    {
        _TimeSheetList = value;
    }
    

    我建议避免更改集合并将项目添加到现有集合:

    var items = TimeSheetByEmployeeDataAccessor.GetTimeSheetByEmployee_ByFromTo(dtpfrom.SelectedDate.GetValueOrDefault(), dtpto.SelectedDate.GetValueOrDefault(), EmployeeID);
    TimeSheetList.Clear();
    foreach(var item in items)
        TimeSheetList.Add(item);
    

    ...或者如果您更喜欢更改收藏(就像现在所做的那样),请发出通知

    set
    {
        _TimeSheetList = value;
        RaisePropertyChange("TimeSheetList");
    }
    

    【讨论】:

    • 好的,我会测试的,我会让你知道的。谢谢
    • 我将通过foreach循环重新添加ObservableCollection进行测试(ObservableCollection中没有AddRange)。它是工作。但是在set中添加RaisePropertyChange是不工作。我有兴趣将RaisePropertyChange 添加到set,而不是添加foreach 循环。你能用完整的示例代码解释RaisePropertyChange 吗?感谢您的帮助。
    • @Loran,你也许有this issue?对不起AddRange,我的项目中有这样的扩展方法(内部使用foreach+Add())
    • 哦,谢谢你的链接,这正是我想要的。现在我得到了我想要的。
    猜你喜欢
    • 1970-01-01
    • 2011-08-15
    • 2012-11-07
    • 1970-01-01
    • 2016-08-07
    • 1970-01-01
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多