我有一个称为ModuleButton的UserControl。该UC具有一些DependencyProperties和一些公共ICommand属性。我试图让该按钮执行两个ICommand,当单击该按钮并选中该复选框时,它们就会执行该操作。但是,单击它们不会执行任何操作。
我首先在按钮和复选框上都使用了click事件,但是,当调用属性“ Module”时,它将说为null。本着尝试在MVVM中执行此操作的精神,我将其移至RelayCommands,以为可能是DataContext问题。我知道DependencyProperties可以正常工作,因为我在XAML方面已绑定到它们,并且一切看起来都很好。我什至绑定了复选框文本以使用ToString转换器显示我的“ Module”属性,因为我确信这并没有正确绑定。我没有找到与我的特定问题有关的任何内容。我怀疑这与我的ICommand属性有关,与我的DependencyProperties不在同一个上下文中。
ModuleButton.xaml
除了无DependencyProperties绑定之外,所有绑定在这里都有效。我目前没有绑定复选框命令,因为我想先对按钮命令进行故障排除。
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<Button Style="{DynamicResource BaseButton}" Command="{Binding ModuleButtonClickCommand}" Content="{Binding Text}" Margin="5"/>
<DockPanel Grid.Row="1" Margin="0,0,0,4">
<CheckBox VerticalAlignment="Center" Content="{Binding Module, Converter={StaticResource ToString}}" IsChecked="{Binding IsChecked}" HorizontalAlignment="Left" Foreground="#FFE8E8E8" Margin="0" Style="{DynamicResource myCheckboxStyle}"/>
<Image Source="/Resources/Info-24.png" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0" ToolTip="{Binding Description}"/>
</DockPanel>
</Grid>
ModuleButton.xaml.cs
RelayCommand从不执行,它们可以在我程序的其他部分中工作,而这些部分没有与DependencyProperties混合在一起。
public partial class ModuleButton : UserControl
{
public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
"Text", typeof(string), typeof(ModuleButton),
new PropertyMetadata("Default Text")
);
public static readonly DependencyProperty DescriptionProperty = DependencyProperty.Register(
"Description", typeof(string), typeof(ModuleButton),
new PropertyMetadata("Default Description")
);
public static readonly DependencyProperty PageProperty = DependencyProperty.Register(
"Page", typeof(Uri), typeof(ModuleButton),
new PropertyMetadata(null)
);
public static readonly DependencyProperty ModuleProperty = DependencyProperty.Register(
"Module", typeof(IModule), typeof(ModuleButton),
new PropertyMetadata(null)
);
public static readonly DependencyProperty IsCheckedProperty = DependencyProperty.Register(
"IsChecked", typeof(bool), typeof(ModuleButton),
new PropertyMetadata(false)
);
public string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); }
public string Description { get => (string)GetValue(DescriptionProperty); set => SetValue(DescriptionProperty, value); }
public Uri Page { get => (Uri)GetValue(PageProperty); set => SetValue(PageProperty, value); }
public IModule Module { get => (IModule)GetValue(ModuleProperty); set => SetValue(ModuleProperty, value); }
public bool IsChecked { get => (bool)GetValue(IsCheckedProperty); set => SetValue(IsCheckedProperty, value); }
public event EventHandler FavoriteIsCheckedChanged;
public ModuleButton()
{
InitializeComponent();
FavoriteCheckboxClickedCommand = new RelayCommand(param => FavoriteCheckboxClicked());
ModuleButtonClickCommand = new RelayCommand(param => ModuleButtonClick());
}
public ICommand FavoriteCheckboxClickedCommand { get; private set; }
public ICommand ModuleButtonClickCommand { get; private set; }
private void FavoriteCheckboxClicked()
{
FavoriteIsCheckedChanged?.Invoke(this, new EventArgs() { });
}
private void ModuleButtonClick()
{
MessageBox.Show("ModuleButtonClick");
}
}
这是所有显示在其中的标签控件。
<Page.DataContext>
<viewmodels:MainToolPageViewModel/>
</Page.DataContext>
<TabControl x:Name="Tabs" Margin="5" ItemsSource="{Binding Tabs}">
<TabControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Header}"/>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Content}"/>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
这是“选项卡”列表及其内容区域的填充方式。
var cats = ModuleManager.GetCategories();
foreach (var cat in cats.list.OrderBy(x => x.index))
{
var buttonsHost = new ModulesButtonHostView();
foreach (var mod in ModuleManager.LoadedModules.Where(x => x.Category == cat.name))
{
buttonsHost.Modules.Add(new ModuleItem {
Text = mod.Name,
Module = mod,
Description = mod.Description,
Page = mod.Page
});
}
Tabs.Add(new MyTabItem() {
Header = cat.name,
Content = buttonsHost
});
}
ModulesButtonHostView.xaml
模块是具有与ModuleButton控件上的DependencyProperties相同属性的ModuleItem列表。
<ItemsControl ItemsSource="{Binding Modules}" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<ItemsControl.ItemTemplate>
<DataTemplate>
<controls:ModuleButton/>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel FlowDirection="LeftToRight"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
我希望发生的事情是,当我单击“模块按钮”时,它能够使用Module属性来加载该模块,而我的那部分代码正在工作,这实际上是使用RelayCommand,我不知道为什么它为空。
编辑:
添加具有约束力建议的问题图片
答案 0 :(得分:0)
您应将绑定的源或DataContext
设置为UserControl
本身:
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
<Grid.RowDefinitions>
<RowDefinition Height="50*"/>
<RowDefinition Height="20*"/>
</Grid.RowDefinitions>
<Button Style="{DynamicResource BaseButton}" Command="{Binding ModuleButtonClickCommand}" Content="{Binding Text}" Margin="5"/>
<DockPanel Grid.Row="1" Margin="0,0,0,4">
<CheckBox VerticalAlignment="Center" Content="{Binding Module, Converter={StaticResource ToString}}" IsChecked="{Binding IsChecked}" HorizontalAlignment="Left" Foreground="#FFE8E8E8" Margin="0" Style="{DynamicResource myCheckboxStyle}"/>
<Image Source="/Resources/Info-24.png" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,5,0" ToolTip="{Binding Description}"/>
</DockPanel>
</Grid>
如果不这样做,运行时将在ModuleItem
类中查找这些属性。