WPF DataGrid的DataBindingComplete事件在哪里?

5

在数据绑定完成后,我需要采取一些行动(例如,基于其他单元格使某些单元格只读)。在WinForm DataGridView中,我通常会在DataBindingComplete事件中进行操作。然而,在WPF DataGrid中,我找不到这样的事件。我还能使用什么?


数据绑定完成后,您想执行什么操作? - Prince Ashitaka
1
正如我在问题中所述,我想根据同一行上另一列的值使某些单元格无效。 - newman
6个回答

8
这是我得出的结论:DataContextChanged事件是正确的事件。唯一的问题是,在此事件内部,datagrid还没有准备好被我的代码消耗。然而,如果我使用Dispatcher.BeginInvoke就可以正常工作,像这样:
Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => DoSomethingWithGrid()));

有人能解释一下为什么这是必要的吗?

实际上,在处理WPF DataGrid时,我不得不在很多情况下使用Dispatcher才能使它正常工作。为什么?


此事件可能会在数据绑定完成之前触发。请参阅http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.datacontextchanged.aspx上的重要备注。 - Wouter

2

我想根据行的属性值对它们进行着色,并尝试了许多事件(DataGrid.InitializedDataContextChangedAddingNewItemRowLoaded等)以及使用 BeginInvoke,但没有任何效果。后来我发现:

Loaded

该事件成功解决了我的问题,因为它允许我遍历行并按照期望的方式着色。

private void SubjectsList_Loaded(object sender, RoutedEventArgs e)
{
    Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => ColorMyRows()));
}

CollorMyRows 看起来与这个很相似:

private void ColorMyRows()
{
    DataGridRow row = null;
    for (int i = 0; i < SubjectsList.Items.Count; i++)
    {
        // get one row
        row = SubjectsList.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow;
        if (myConditionIsFulfilled)
        {
            row.Background = Brushes.PaleGoldenrod; // black'n gold baby
            row.ToolTip = "This item fulfills the condition.";
        }
        else
        {
            row.Background = Brushes.PaleGreen;
            row.ToolTip = "This item does not.";
        }
    }
}

注意:如果您将ObservableCollection绑定到DataGrid,则循环中的索引(DataGrid行的索引)将对应于集合中的索引 :)

1

DataContextChanged。


我认为你可以通过使用IValueConverter和样式设置来相对容易地完成这个任务。我可以为此编写一个示例,但需要几天时间。 - Chris Holmes
@Chris:我对你使用IValueConverter和Style的建议非常感兴趣。你能否提供一些示例代码给我?谢谢! - newman
@miliu 看起来在样式和IValueConverters中无法针对单个单元格设置IsReadOnly。只能在列级别上进行设置。所以,很遗憾,我无法提供任何有助于您特定情况的代码。抱歉miliu。我希望它能够奏效。 - Chris Holmes
@Chris:无论如何还是谢谢。我希望微软在下一个版本中能够添加单元格级别的只读/读写属性。与此同时,我想我必须使用WPF工具包数据网格,以便我可以直接更改源代码。 - newman
1
此事件可能在数据绑定完成之前触发。请参阅http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.datacontextchanged.aspx上的重要备注。 - Wouter
显示剩余2条评论

1

也许你正在使用线程,而datagrid作为所有UI组件并不是线程安全的。


0

你可以将单元格的只读属性绑定到一个随着模型其他属性变化而变化的属性。 我以前也曾像你一样考虑,但现在更多地关注于模型而非视图。我对DataGrid不感兴趣,但对绑定到列表的数据感兴趣,你可以做同样的事情。 我之前在类似情况下使用过它。

public class Model : INotifyPropertyChanged
    {
public bool IsChecked
        {
            get { return isChecked; }
            set
            {
                isChecked = value;
                RaisePropertyChanged("IsChecked");
                RaisePropertyChanged("Visibilty");
            }
        }
public Visibility Visibilty
        {
            get
            {
                return IsChecked ? Visibility.Visible : Visibility.Hidden;
            }
        }
}

这是一个绑定到IsChecked属性的数据网格中的复选框,其他单元格绑定到可见性,对我而言它很有效。希望这可以帮到你。


0
你可以声明一个BackgroundWorker,并尝试在DoWork事件中填充你的GridView,然后在RunWorkerCompleted事件中编写你的代码。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接