【问题标题】:Datagrid SelectedIndex binding won't work in XAMLDatagrid SelectedIndex 绑定在 XAML 中不起作用
【发布时间】:2017-04-15 08:37:07
【问题描述】:

问题摘要:XAML 中是否有办法确保我的 DataGrid 组件在启动对 SelectedIndex 属性的绑定之前已完全加载?


我的 ViewModel 是这样设置的。我正在使用 MVVM-light 来通知视图的更改。每当它从服务器更新时,我都会将新模型传递给SetData()

public class MyViewModel : ViewModelBase
{
    public void SetData(DataModel model)
    {                
        Data = model.Data; //Array of 75 DataObjects
        DataIndex = model.Index; //int between 0 and 74
    }

    // Array to Bind to Datagrid ItemsSource
    public DataObject[] Data 
    {
        get { return _data; }
        private set
        {
            if (_data!= value)
            {
                _data= value;
                RaisePropertyChanged("Data");
            }
        }
    }
    private DataObject[] _data;

    // Int to Bind to Datagrid SelectedIndex
    public int DataIndex
    {
        get { return _index; }
        private set
        {
            if (_index != value)
            {
                _index = value;
                RaisePropertyChanged("DataIndex");
            }
        }
    }
    private int _index;
}

视图如下所示:

<Application.Resources>
    <ResourceDictionary>
        <core:ViewModelLocator x:Key="Locator" />
    </ResourceDictionary>
</Application.Resources>

<DataGrid ItemsSource="{Binding MyViewModel.Data, Source={StaticResource Locator}}"
          SelectedIndex="{Binding MyViewModel.DataIndex, Source={StaticResource Locator}, Mode=OneWay}"
          AutoGenerateColumns="True"/>

我的问题是我的 DataGrid 上没有选择任何行。所有数据都正确显示在网格中,但未选择行。我检查了属性并确认数组长度为 75,DataIndex 是 0 到 74 之间的 int。


原因似乎是因为在设置绑定时 DataGrid 尚未完成加载。我可以通过在组件加载后初始化绑定来证明这一点。在这种情况下,一切都按预期工作,并且我选择的项目正确显示:

<DataGrid x:Name="MyDataGrid" Loaded="OnDataGridLoaded"
          ItemsSource="{Binding MyViewModel.Data, Source={StaticResource Locator}}"
          AutoGenerateColumns="True"/>

private void OnDataGridLoaded(object sender, RoutedEventArgs e)
{
    Binding b = new Binding("DataIndex");
    b.Source = Locator.MyViewModel.Data;
    MyDataGrid.SetBinding(DataGrid.SelectedIndexProperty, b);
}

我不想这样做,因为,你知道,代码隐藏。那么有没有办法只使用 XAML 来解决这个问题?这是我迄今为止尝试过的(没有一个对我有用):

  • 将 SelectedIndex 绑定到我的 ViewModel 上的 int 属性(如上所示)
  • 将 SelectedItem 绑定到我的 ViewModel 上的 DataObject 属性(结果相同)
  • 将 SelectedValue 和 SelectedPath 绑定到我的 DataObject 的属性(这实际上有效,仅适用于第一个实例。问题是我有这个 Datagrid 组件的多个实例,出于某种原因,这只适用于第一个实例)
  • 绑定到 ObservableCollection 而不是 Array(使用 ObservableCollection 尝试了上述所有 3 种方法,并且每种方法都获得了相同的结果)
  • 通过将更改通知包装在对Dispatcher.Invoke 的调用中来延迟更改通知。这无济于事,因为该组件并未立即显示在视图中。
  • 在 XAML 中创建绑定,然后在 Loaded 函数中更新目标。 MyDataGrid.GetBindingExpression(DataGrid.SelectedIndexProperty).UpdateTarget();

【问题讨论】:

  • @Clemens 谢谢,注意到了。这段代码是我实际程序的浓缩摘要,其中 DataGrid 的源是一个单独的对象,而不是 UserControl 的 DataContext。但无论如何,所有优点。
  • 你为什么不在Window.Loaded事件上第一次打电话给setData
  • @EdPlunkett 抱歉,我忘了在这段代码中包含它。但是,是的,我已将绑定设置为一种方式
  • @esiprogrammer 我不确定你的意思,但让我澄清一下。我有多个组件实例,默认情况下所有这些实例都不在视图中。一旦用户按下按钮,就会创建组件并用数据填充网格。换句话说,数据在显示在组件中之前就已经提前存储好了。
  • 我猜问题可能出在视图的设置DataContext 上。这就是为什么你提供的代码隐藏工作。你在哪里设置DataContext

标签: c# wpf xaml data-binding wpfdatagrid


【解决方案1】:

我最初的问题是缺少一条导致问题的信息。 当绑定源是静态链接时,似乎存在 WPF 错误。如果我将DataIndex 属性移动到组件的DataContext 中,那么它将正常工作。

不过,我不打算这样做,因为数据在多个实例之间共享。我不需要数据的多个实例,只需要组件。因此,我将把它作为微软的 bug 改正,并使用代码隐藏解决方法。

我会留下这个问题,以防万一有人对此错误有解决方案。

【讨论】:

    猜你喜欢
    • 2020-05-16
    • 2014-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-16
    • 2016-09-09
    • 1970-01-01
    • 2017-12-11
    相关资源
    最近更新 更多