我是WPF的新手,我试图在ContentControl中动态添加一个Button,它应该在点击时触发一个命令。我使用MVVMLight来处理命令。
下面我有一个带两个按钮的例子。顶部按钮直接放在StackPanel中。此按钮按预期触发命令。
第二个按钮放在ContentControl中。它显示正确,但单击按钮时命令不会触发。 我假设这是因为Binding没有通过DataTemplate向下传输,但是如果我使用常规命令而不是MVVMLight RelayCommands它似乎有效。
我不想删除框架,所以我想知道是否有人知道如何修复它?感谢
<Window x:Class="ContentControlExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:ContentControlExample.ViewModel">
<Window.DataContext>
<vm:MainViewModel />
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="MyButton" >
<Button Content="SUBMIT" Command="{Binding MyCommand}" Width="200" Height="50"/>
</DataTemplate>
</Window.Resources>
<StackPanel>
<!--When this button is clicked, the Command executes as expected-->
<Button Content="SUBMIT" Command="{Binding MyCommand}" Width="200" Height="50"/>
<!--Nothing happens when this button is clicked-->
<ContentControl ContentTemplate="{StaticResource MyButton}"/>
</StackPanel>
</Window>
这里是带有命令的ViewModel:
public class MainViewModel : ViewModelBase
{
public ICommand MyCommand { get; private set; }
public MainViewModel()
{
MyCommand = new RelayCommand(MyCommand_Executed, MyCommand_CanExecute);
}
private bool MyCommand_CanExecute()
{
return true;
}
private void MyCommand_Executed()
{
MessageBox.Show("The command executed");
}
}
答案 0 :(得分:1)
这里的问题是ContentTemplate
中的隐式DataContext是Content
,并且没有设置为任何内容。您需要将Content
设置为某个Binding以桥接当前可视树中的DataContext
,如下所示:
<ContentControl ContentTemplate="{StaticResource MyButton}" Content="{Binding}"/>
答案 1 :(得分:1)
另一个解决方案是给你的窗口命名:
<Window x:Class="ContentControlExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:vm="clr-namespace:ContentControlExample.ViewModel"
x:Name="_this">
然后通过其上下文绑定:
<Button Content="SUBMIT" Command="{Binding ElementName=_this, Path=DataContext.MyCommand}" Width="200" Height="50"/>
这对于像ListViews和ItemControls这样的东西特别方便,因为它们的DC被设置为列表元素。请记住,这只适用于同一视觉树中的成员,如果不是这种情况(例如弹出菜单等),那么您需要代理绑定as described in this article。