another one
,但差异很大,因此我认为有必要将其放在这里。)
这是一个(被严重剪断的)
Window
:
<Window x:Class="Gmd.TimeTracker2.TimeTrackerMainForm"
xmlns:local="clr-namespace:Gmd.TimeTracker2"
xmlns:localcommands="clr-namespace:Gmd.TimeTracker2.Commands"
x:Name="This"
DataContext="{Binding ElementName=This}">
<Window.CommandBindings>
<CommandBinding Command="localcommands:TaskCommands.ViewTaskProperties"
Executed="HandleViewTaskProperties"
CanExecute="CanViewTaskPropertiesExecute" />
</Window.CommandBindings>
<DockPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Content="_Create a new task" Grid.Row="1" x:Name="btnAddTask" Click="HandleNewTaskClick" />
</Grid>
</DockPanel>
</Window>
UserControl
<UserControl x:Class="Gmd.TimeTracker2.TaskStopwatchControl"
xmlns:local="clr-namespace:Gmd.TimeTracker2"
xmlns:localcommands="clr-namespace:Gmd.TimeTracker2.Commands"
x:Name="This"
DataContext="{Binding ElementName=This}">
<UserControl.ContextMenu>
<ContextMenu>
<MenuItem x:Name="mnuProperties" Header="_Properties" Command="{x:Static localcommands:TaskCommands.ViewTaskProperties}"
CommandTarget="What goes here?" />
</ContextMenu>
</UserControl.ContextMenu>
<StackPanel>
<TextBlock MaxWidth="100" Text="{Binding Task.TaskName, Mode=TwoWay}" TextWrapping="WrapWithOverflow" TextAlignment="Center" />
<TextBlock Text="{Binding Path=ElapsedTime}" TextAlignment="Center" />
<Button Content="{Binding Path=IsRunning, Converter={StaticResource boolToString}, ConverterParameter='Stop Start'}" Click="HandleStartStopClicked" />
</StackPanel>
</UserControl>
通过各种技术,一个
可以动态添加到
窗
从xaml可以看出,我认为尝试使用命令作为处理用户可以执行的各种操作的方式是有意义的
Task
s我这样做的最终目标是将所有命令逻辑分解成一个更正式定义的控制器层,但我试图一步一步地重构。
我遇到的问题与
用户控制
ContextMenu
CanExecute
用户控制
窗
试图执行
ViewTaskProperties
指挥部
CanExecute
处理程序从不运行,菜单项保持禁用状态。如果我然后单击某个UI元素(例如,按钮)只是为了给某个焦点,那么
CanExecute
处理程序使用
CanExecuteRoutedEventArgs
任务
不是元素,所以我不认为它可以是源)。
我想可能是我错过了比赛
CommandTarget
土地上的财产
MenuItem
用户控制
<MenuItem x:Name="mnuProperties"
Header="_Properties"
Command="{x:Static localcommands:TaskCommands.ViewTaskProperties}"
CommandTarget="{Binding ElementName=This}" />
由于绑定无效,此操作失败。我不知道为什么。然后我想,“嗯,我在找树,也许我需要的是一个相对资源”,我试了一下:
<MenuItem x:Name="mnuProperties"
Header="_Properties"
Command="{x:Static localcommands:TaskCommands.ViewTaskProperties}"
CommandTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:TaskStopwatchControl}}}" />
上下文菜单
<MenuItem x:Name="mnuProperties"
Header="_Properties"
Command="{x:Static localcommands:TaskCommands.ViewTaskProperties}"
CommandTarget="{Binding RelativeSource={x:Static RelativeSource.Self}}" />
这也失败了。
像这样一次失败的猜测和检查足以让我退缩,并意识到我在这里遗漏了一些基本概念。那我该怎么办?
-
这提供了修改命令源的机制,是否正确?
-
我如何从一个文件夹绑定
在里面
UserControl.ContextMenu
给拥有者
? 或者我做错事仅仅是因为我觉得有必要这么做?
-
我希望由单击以生成上下文菜单的元素设置命令的上下文,而不是在上下文菜单之前具有焦点的元素,这是不正确的吗?也许我需要编写自己的命令,而不是使用
RoutedUICommand
private static RoutedUICommand viewTaskPropertiesCommand = new RoutedUICommand("View a task's details.", "ViewTaskProperties", typeof(TaskCommands));
public static RoutedUICommand ViewTaskProperties
{
get { return viewTaskPropertiesCommand; }
}
-
我的设计中是否存在一些更深层次的基本缺陷?这是我的第一个重要的WPF项目,我在自己的时间里做这件事,作为一种学习经验,所以我绝对不反对学习一个优秀的解决方案体系结构。