我遇到了这个问题,我在MainWindow中定义了所有这些CommandBindings,并且在该窗口中可以使用所述命令在任何Button或MenuItem中使用。问题是,如果在其他窗口中命令绑定不可用(它总是假的),即使新窗口的所有者是MainWindow。
任何帮助都非常感激。
这是代码。
XAML MainWindow:
<Window x:Class="ContextMenuDialogProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ContextMenuDialogProblem"
Title="MainWindow" Height="350" Width="525"
FocusManager.FocusedElement="{Binding RelativeSource={x:Static RelativeSource.Self}, Mode=OneTime}">
<Window.CommandBindings>
<CommandBinding Command="local:LocalCommandManager.ShowDialogCommand" CanExecute="CanExecuteShowDialogCommand" Executed="ShowDialogCommandExecuted" />
</Window.CommandBindings>
<Window.ContextMenu>
<ContextMenu>
<MenuItem Command="local:LocalCommandManager.ShowDialogCommand" />
</ContextMenu>
</Window.ContextMenu>
<Grid Background="Red">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0"
Content="Open SubWindow"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="6"
Click="Button_Click" />
<Button Grid.Row="1"
Content="Show Dialog Command Test"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="6"
Command="local:LocalCommandManager.ShowDialogCommand" />
</Grid>
</Window>
CS MainWindow:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void CanExecuteShowDialogCommand(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
private void ShowDialogCommandExecuted(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Show Dialog");
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Window wnd = new SubWindow() { Owner = this };
wnd.Show();
}
}
CS LocalCommandManager:
public static class LocalCommandManager
{
private static object syncRoot = new object();
private static RoutedUICommand _showDialogCommand;
public static RoutedUICommand ShowDialogCommand
{
get
{
lock (syncRoot)
{
if (_showDialogCommand == null)
_showDialogCommand = new RoutedUICommand("Show Dialog", "ShowDialogCommand", typeof(LocalCommandManager));
return _showDialogCommand;
}
}
}
}
XAML SubWindow:
<Window x:Class="ContextMenuDialogProblem.SubWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:local="clr-namespace:ContextMenuDialogProblem"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SubWindow" Height="300" Width="300">
<Grid>
<Button Command="local:LocalCommandManager.ShowDialogCommand" Content="Show Dialog" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="6" />
</Grid>
</Window>
答案 0 :(得分:3)
CommandBindings
的范围仅限于定义它的元素,因此这种行为完全正常。如果您想在CommandBinding
使用它,则必须将SubWindow
添加到{{1}}。
答案 1 :(得分:1)
<StackPanel Background="Transparent">
<StackPanel.ContextMenu>
<ContextMenu ItemsSource="{Binding Path=AnotherWindow.CommandBindings}">
<ContextMenu.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<Setter Property="Header" Value="{Binding Path=Command.Name}" />
<Setter Property="Command">
<Setter.Value>
<MultiBinding Converter="{StaticResource commandConverter}">
<Binding />
<Binding RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType={x:Type ContextMenu}}" />
</MultiBinding>
public class CommandConverter : IMultiValueConverter
{
public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var cb = value[0] as CommandBinding;
var cm = value[1] as ContextMenu;
if(cb == null || cm == null)
return null;
cm.CommandBindings.Add(cb);
return cb.Command;
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
在.net 4.0上正常工作
答案 2 :(得分:0)
如果要为所有窗口添加命令,这是解决方案:
public partial class App : Application
{
public App()
{
var binding = new CommandBinding(MyCommands.DoSomethingCommand, DoSomething, CanDoSomething);
// Register CommandBinding for all windows.
CommandManager.RegisterClassCommandBinding(typeof(Window), binding);
}
private void DoSomething(object sender, ExecutedRoutedEventArgs e)
{
...
}
private void CanDoSomething(object sender, CanExecuteRoutedEventArgs e)
{
...
e.CanExecute = true;
}
}