MVVM灯很高兴学习,但在这里我被卡住了。问题是事件发生。
在下面的代码中,一个按钮可以工作并触发事件。另一个按钮不是。输出中未报告绑定错误。我有什么明显的遗失吗?
<Grid x:Name="LayoutRoot">...
<StackPanel>
<Button Content="THIS BUTTON WORKS">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Command:EventToCommand Command="{Binding DataContext.HandleAddQuestionActionCommand, ElementName=LayoutRoot, Mode=OneWay}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<sdk1:DataGrid ItemsSource="{Binding QuestionActions}" AutoGenerateColumns="False" >
<sdk1:DataGrid.Columns>
<sdk1:DataGridTextColumn Binding="{Binding Answer.Name}" Header="Answer"/>
<sdk1:DataGridTemplateColumn Header="Edit">
<sdk1:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="THIS BUTTON DONT WORK" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Command:EventToCommand Command="{Binding DataContext.HandleEditQuestionActionCommand, ElementName=LayoutRoot, Mode=OneWay}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
</sdk1:DataGridTemplateColumn.CellTemplate>
</sdk1:DataGridTemplateColumn>
</sdk1:DataGrid.Columns>
</sdk1:DataGrid>
</StackPanel>
ViewModel代码:
public RelayCommand<RoutedEventArgs> HandleAddQuestionActionCommand {
get; private set;
}
public RelayCommand<RoutedEventArgs> HandleEditQuestionActionCommand {
get; private set;
}
HandleAddQuestionActionCommand = new RelayCommand<RoutedEventArgs>(e =>{...});
HandleEditQuestionActionCommand = new RelayCommand<RoutedEventArgs>(e =>{...});
答案 0 :(得分:11)
您的数据上下文在DataGrid DataGridTemplateColumn中丢失,因为DataGrid.Columns不是依赖项属性。因此,您不能在DataGridTemplateColumn中使用元素到元素的数据绑定。
然而,由于MVVM Light Toolkit的ViewModelLocator,这很容易解决。
我不知道您的ViewModel被调用了什么,但假设它是MainViewModel,您可以将按钮绑定更改为:
<sdk1:DataGridTemplateColumn Header="Edit">
<sdk1:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="THIS BUTTON WILL WORK NOW ;-)" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Command:EventToCommand Command="{Binding Source={StaticResource Locator},
Path=MainViewModel.HandleEditQuestionActionCommand}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
</sdk1:DataGridTemplateColumn.CellTemplate>
</sdk1:DataGridTemplateColumn>
答案 1 :(得分:0)
DataGrid中的按钮具有QuestActions的DataContext,因为Binding基于DataGrid的ItemSource属性。在这种情况下,您需要找到DataGrid本身的DataContext(或UserControl或其中具有Command的DataContext中的任何父级)才能访问您的Command:
<Command:EventToCommand
Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type sdk1:DataGrid}},
Path=DataContext.ViewSchemaCommand, Mode=OneWay}"
PassEventArgsToCommand="True" />
答案 2 :(得分:0)
此解决方案仅适用于静态视图模型。查看Dan Whalin的页面,寻找替代答案。 http://weblogs.asp.net/dwahlin/archive/2009/08/20/creating-a-silverlight-datacontext-proxy-to-simplify-data-binding-in-nested-controls.aspx
您可以创建这样的资源(不要忘记您的参考资料):
<UserControl.Resources>
<controls:DataContextProxy x:Key="DataContextProxy" />
</UserControl.Resources>
或
<sdk:Page.Resources>
<controls:DataContextProxy x:Key="DataContextProxy"/>
</sdk:Page.Resources>
在控件中使用如下:
<sdk:DataGridTemplateColumn>
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="Content">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand Command="{Binding Source={StaticResource DataContextProxy}, Path=DataSource.MyCommand}"
CommandParameter="{Binding Path=SomeValue}"
PassEventArgsToCommand="False">
</cmd:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
视图模型 定义RelayCommand:
public RelayCommand<object> MyCommand { get; set; }
在构造函数中设置RelayCommand:
MyCommand = new RelayCommand<object>((e) =>
{
if (e != null && e is int)
{
int varName = int.Parse(e.ToString());
//DoSomething...
}
});