ICommand 在 Silverlight 用户控件中不起作用
ICommand not working in Silverlight User control
我有一个带网格的 UserControlBase
。网格包含一个带有操作的列。
<sdk:DataGridTemplateColumn Header="Action">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<Button Style="{StaticResource DataGridButton}" Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}" Content="Modify" />
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
我的问题出在 Command
上。它向我抛出技术错误,这是我的第一个问题,我不知道如何让这个应用程序向我抛出真正的错误消息。
在我的用户控件后面的代码中,我注册了事件:
protected void RegisterMessages()
{
Messenger.Default.Register<string>(this, "NewNewsBtn_Click", NewNewsBtn_Click);
Messenger.Default.Register<string>(this, "ModifyNewsBtn_Click", ModifyNewsBtn_Click);
}
在我的构造函数中:
public NewsWindow(int underlyingId)
{
InitializeComponent();
this.RegisterMessages();
viewModel = new NewsViewModel(underlyingId);
ucNewsPanel.DataContext = viewModel;
}
我的视图模型 (NewsViewModel)
public ICommand ModifyNewsCommand
{
get
{
return new RelayCommand<string>(e =>
{
Messenger.Default.Send(string.Empty, "ModifyNewsBtn_Click");
});
}
}
奇怪的是我的 NewNewsBtn
在工作,而我的 ModifyNewsBtn
没有。
此按钮位于网格之外,因此它的工作原理可能有所不同。
<Button x:Name="NewNewsBtn" MaxHeight="50" MaxWidth="100" Command="{Binding Path=NewNewsCommand}" Content="Add New" />
你的语法看起来没问题:
<Button Style="{StaticResource DataGridButton}" Content="Modify"
Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}"/>
但是你在代码中设置了 viewModel。你在 XAML 中创建 StaticResource
我说得对吗?如果是,则只需从代码隐藏中删除设置 DataContext
,因为下一行 Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}"
将在您的 viewModel 的另一个实例中看到。 (因为您已经创建了 NewsViewModel
的两个实例作为 StaticResource
和代码隐藏)
更新:
当我将参数传递给我的视图模型时,我需要代码隐藏中的 DataContext。如果我从后面的代码中删除它,有什么办法可以做到这一点?
那么你应该从 Command
:
的绑定中删除 StaticResource
<Button Style="{StaticResource DataGridButton}" Command="{Binding ModifyNewsCommand}"
Content="Modify"/>
因为您正在引用 NewsViewModel
的另一个实例。
您的 DataGrid 将绑定到某个集合,每个项目一行。现在该项目是一行的 DataContext。您需要做的是将 "Modify"-button 绑定到父 DataContext。如果您使用的是 silverlight5,则可以使用 AncestorBinding
:
<Button
Content="Modify"
Command="{Binding
Path=DataContext.ModifyNewsCommand,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>
我有一个带网格的 UserControlBase
。网格包含一个带有操作的列。
<sdk:DataGridTemplateColumn Header="Action">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<Button Style="{StaticResource DataGridButton}" Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}" Content="Modify" />
</StackPanel>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
我的问题出在 Command
上。它向我抛出技术错误,这是我的第一个问题,我不知道如何让这个应用程序向我抛出真正的错误消息。
在我的用户控件后面的代码中,我注册了事件:
protected void RegisterMessages()
{
Messenger.Default.Register<string>(this, "NewNewsBtn_Click", NewNewsBtn_Click);
Messenger.Default.Register<string>(this, "ModifyNewsBtn_Click", ModifyNewsBtn_Click);
}
在我的构造函数中:
public NewsWindow(int underlyingId)
{
InitializeComponent();
this.RegisterMessages();
viewModel = new NewsViewModel(underlyingId);
ucNewsPanel.DataContext = viewModel;
}
我的视图模型 (NewsViewModel)
public ICommand ModifyNewsCommand
{
get
{
return new RelayCommand<string>(e =>
{
Messenger.Default.Send(string.Empty, "ModifyNewsBtn_Click");
});
}
}
奇怪的是我的 NewNewsBtn
在工作,而我的 ModifyNewsBtn
没有。
此按钮位于网格之外,因此它的工作原理可能有所不同。
<Button x:Name="NewNewsBtn" MaxHeight="50" MaxWidth="100" Command="{Binding Path=NewNewsCommand}" Content="Add New" />
你的语法看起来没问题:
<Button Style="{StaticResource DataGridButton}" Content="Modify"
Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}"/>
但是你在代码中设置了 viewModel。你在 XAML 中创建 StaticResource
我说得对吗?如果是,则只需从代码隐藏中删除设置 DataContext
,因为下一行 Command="{Binding Source={StaticResource NewsViewModel}, Path=ModifyNewsCommand}"
将在您的 viewModel 的另一个实例中看到。 (因为您已经创建了 NewsViewModel
的两个实例作为 StaticResource
和代码隐藏)
更新:
当我将参数传递给我的视图模型时,我需要代码隐藏中的 DataContext。如果我从后面的代码中删除它,有什么办法可以做到这一点?
那么你应该从 Command
:
StaticResource
<Button Style="{StaticResource DataGridButton}" Command="{Binding ModifyNewsCommand}"
Content="Modify"/>
因为您正在引用 NewsViewModel
的另一个实例。
您的 DataGrid 将绑定到某个集合,每个项目一行。现在该项目是一行的 DataContext。您需要做的是将 "Modify"-button 绑定到父 DataContext。如果您使用的是 silverlight5,则可以使用 AncestorBinding
:
<Button
Content="Modify"
Command="{Binding
Path=DataContext.ModifyNewsCommand,
RelativeSource={RelativeSource AncestorType=UserControl}}"/>