2016-11-30 5 views
0

質問の概要: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();
+0

@クレメンスありがとうございます。このコードは、DataGridのソースがUserControlのDataContextとは別のオブジェクトである私の実際のプログラムの要約です。しかし、関係なく、すべての良い点。 – Karmacon

+0

初めてWindow.Loadedイベントで 'setData'を呼び出さないでください。 – esiprogrammer

+1

@EdPlunkett申し訳ありませんが、私はこのコードにそれを含めるのを忘れていました。しかし、はい、私は束縛を一方向に設定しました – Karmacon

答えて

0

私の元の質問には、問題の原因となった情報が欠落していました。 バインディングソースが静的リンクの場合、WPFのバグがあるようです。 DataIndexプロパティをコンポーネントのDataContextに移動すると、正しく動作します。

ただし、データは複数のインスタンス間で共有されるため、これは行いません。私はデータの複数のインスタンスを持つ必要はなく、コンポーネントだけです。そのため、私はMicrosoftのバグとしてすぐに取り除き、コードビハインドの作業を使用します。

誰かがこのバグの解決策を持っている場合に備えて、質問を開いたままにします。

関連する問題