问题摘要:在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解决这个问题?这是我迄今为止尝试过的(其中没有一个对我有用):
int
属性(如上所示)DataObject
属性(相同结果)DataObject
的属性(这实际上只适用于第一个实例。问题是我有这个Datagrid组件的多个实例,并且由于某种原因,这仅适用于第一个实例)Dispatcher.Invoke
的调用中来延迟更改通知。这没有用,因为组件不会立即被查看。MyDataGrid.GetBindingExpression(DataGrid.SelectedIndexProperty).UpdateTarget();
答案 0 :(得分:0)
我原来的问题是遗漏了引起问题的一条信息。
当绑定源是静态链接时,似乎存在WPF错误。如果我将DataIndex
属性移动到组件的DataContext中,那么它将正常工作。
但是我不打算这样做,因为数据是在多个实例之间共享的。我不需要有多个数据实例,只需要组件。因此,我将把它作为微软的错误,并使用代码隐藏的工作。
如果有人能解决这个错误的话,我会把这个问题打开。