質問
2013年6月17日月曜日 4:57 | 1 票
こんにちは。
タイトルの内容なのですが、練習でMVVMを利用したプログラムを作成しています。
その中で、データグリッド内にボタンを追加して、ボタンが押された時のClickイベントでDelegateCommandで用意したメソッドを実行させようとしているのですが、うまく動きません。
ちなみに、通常のボタンだとDelegateCommandはうまく動いていました。
なので、DataContentにViewModelを与えてから、グリッド内が作成させる。そこでようやくボタンが画面上に出てくる関係で、うまくCommandと紐付いていないような気がするのですが、根本的に考え違いがあるのでしょうか?
以上、よろしくお願いします。
<DataGrid Name="ViewGrid" Grid.Row="1" Style="{StaticResource Modan}" ItemsSource="{Binding Pages}" Width="400" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" >
<DataGrid.Columns>
<DataGridTextColumn Width="2*" Header="種別" Binding="{Binding Group}" />
<DataGridTextColumn Width="3*" Header="項目名" Binding="{Binding Name}" />
<DataGridTextColumn Width="1*" Header="閲覧" Binding="{Binding Authority}" />
<DataGridTemplateColumn Header="" Width="2*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="選択" Command="{Binding OnSelectView}" CommandParameter="{Binding SelectedItem, ElementName=ViewGrid}" Margin="-1" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
public DelegateCommand OnSelectView
{
get
{
if (this._onSelectView == null) this._onSelectView = new DelegateCommand(ExecuteOnSelectView);
return this._onSelectView;
}
}
private void ExecuteOnSelectView(object parameter)
{
MessageBox.Show("a");
}
環境
windows 7 pro x32
VisualStudioExpress2012 for windows desktop
すべての返信 (2)
2013年6月17日月曜日 6:10 ✅回答済み | 2 票
もう少しソースを見せていただかないとはっきりわかりませんが、以下のことに注意して確認してみて下さい。
DataGridの各行にバインドしている明細それぞれが、暗黙的にDataGridの各行のDataContextになります。よって、OnSelectViewと単に書いた場合、各行にバインドしている明細の中からOnSelectViewコマンドを探すことになります。一方で、RelativeSourceでDataGridを探し、そのDataContext.OnSelectViewと書いた場合は、DataGridのDataContextプロパティのOnSelectViewということになります。このページのDataContextとしてViewModelを設定しており、DataGridのDataContextを明に指定していないのであれば、DataGridのDataContextはページのDataContextと一致することになります。よって、ViewModelの中からOnSelectViewを探すことになります。
ポイントとしては、DataGridの各行のDataContextはViewModelになっておらず、それぞれの明細オブジェクトがDataContextになっているということです。
★良い回答には回答済みマークを付けよう! わんくま同盟 MVP - Visual C# http://d.hatena.ne.jp/trapemiya/
2013年6月17日月曜日 5:26
すいません。いろいろ調べていたら、次のように修正することで、うまくイベントが繋がるようになりました。
ただ、よくわからないのがCommand側は{Binding DataContent.On***}としたことです。このDataContentは何を指しているのでしょうか? このXAMLファイルPageならPageのDataContentになるのでしょうか。
また、なぜこの箇所だけこういった記述にルールが変わったのか理解しきれていません。何が原因でDataContent.***と書かないとつながらないようになっていたのでしょうか?
<DataGrid Grid.Row="1" Style="{StaticResource Modan}" ItemsSource="{Binding Pages}" Width="400" AutoGenerateColumns="False" IsReadOnly="True" SelectionMode="Single" >
<DataGrid.Columns>
<DataGridTextColumn Width="2*" Header="種別" Binding="{Binding Group}" />
<DataGridTextColumn Width="3*" Header="項目名" Binding="{Binding Name}" />
<DataGridTextColumn Width="1*" Header="閲覧" Binding="{Binding Authority}" />
<DataGridTemplateColumn Header="" Width="2*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="選択" Command="{Binding DataContext.OnSelectView, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" Margin="-1" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
参考