質問の概要:SelectedIndexプロパティでバインディングを開始する前にDataGridコンポーネントが完全にロードされていることをXAMLで確認する方法はありますか?Datagrid SelectedIndexバインディングがXAMLで機能しない
私の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であり、バインディングが設定されている場合、データグリッドのロードが完了していないので、理由があるようだ
0〜74
DataIndex
がintであることが確認されました。私は、コンポーネントがロードされた後にバインディングを初期化することでこれを証明できます。この場合、すべてが期待通りに動作し、私の選択した項目が正しく表示されます。
<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のみを使用してこれを修正する方法はありますか?ここで私は(のどれも私のために働いていない)これまでに試したものです:私のViewModelにint
財産へ
- バインディングSelectedIndexを(上記のように)私のViewModelに
DataObject
財産へ - バインディングのSelectedItem (同じ結果)
- SelectedValueとSelectedPathを、
DataObject
のプロパティにバインドしています(これは実際には最初のインスタンスのみで機能しましたが、このDatagridコンポーネントの複数のインスタンスがあり、何らかの理由でこれが最初のインスタンス) - ObservableCollectionインスタンスへのバインド(上記の3つのメソッドのすべてをObservableCollectionで試してみて、それぞれについて同じ結果が得られた)
Dispatcher.Invoke
への呼び出しで変更通知をラップして遅延させます。コンポーネントがすぐに表示されないため、これは役に立ちません。- XAMLでバインディングを作成し、[読み込み]機能でターゲットを更新します。
MyDataGrid.GetBindingExpression(DataGrid.SelectedIndexProperty).UpdateTarget();
@クレメンスありがとうございます。このコードは、DataGridのソースがUserControlのDataContextとは別のオブジェクトである私の実際のプログラムの要約です。しかし、関係なく、すべての良い点。 – Karmacon
初めてWindow.Loadedイベントで 'setData'を呼び出さないでください。 – esiprogrammer
@EdPlunkett申し訳ありませんが、私はこのコードにそれを含めるのを忘れていました。しかし、はい、私は束縛を一方向に設定しました – Karmacon