Datagrid SelectedIndex绑定在XAML

时间:2016-11-30 21:09:23

标签: c# wpf xaml data-binding wpfdatagrid

问题摘要:在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();

1 个答案:

答案 0 :(得分:0)

我原来的问题是遗漏了引起问题的一条信息。 当绑定源是静态链接时,似乎存在WPF错误。如果我将DataIndex属性移动到组件的DataContext中,那么它将正常工作。

但是我不打算这样做,因为数据是在多个实例之间共享的。我不需要有多个数据实例,只需要组件。因此,我将把它作为微软的错误,并使用代码隐藏的工作。

如果有人能解决这个错误的话,我会把这个问题打开。