开发者

How to access command from MainWindow level in another Window?

开发者 https://www.devze.com 2023-02-10 02:43 出处:网络
I am trying to access commands that are defined in MainWindow.xaml in another window. I am only able to get grayed out titles of these commands. I am wondering what should be should be done in order t

I am trying to access commands that are defined in MainWindow.xaml in another window. I am only able to get grayed out titles of these commands. I am wondering what should be should be done in order to get a full access.

Sample of the command:

public partial class MainWindow : Window
{
    public static RoutedUICommand AddCommand1 = new RoutedUICommand("Command ", "command1", typeof(MainWindow));

    public MainWindow()
    {
        InitializeComponent();
        this.CommandBindings.Add(new CommandBinding(AddCommand1, AddCommand1Executed));
    }

    private void AddCommand1Executed(object sender, ExecutedRoutedEventArgs e)
    {
        AddNewItem picker = new AddNewItem();
        picker.ShowDialog();
    }

I access these command in style through databinding:

<Menu x:Name="TaskMenuContainer"><MenuItem x:Name="menuItem" Header="TASKS" ItemsSource="{Binding}" Template="{DynamicResource TaskMenuTopLevelHeaderTemplateKey}">
<MenuItem.ItemContainerStyle>
    <Style TargetType="{x:Type MenuItem}">
        <Setter Property="Command" Value="{Binding}" />
        <Setter Property="Header" Value="{Binding Text, RelativeSource={RelativeSource Self}}" />
        <Setter Property="CommandTarget" Value="{Binding RelativeSource={RelativeSource Self}}"/>
    </Style>
</MenuItem.ItemContainerStyle>

These commands work in pages that is load开发者_运维问答ed inside MainWindow.xaml through frame. However, if I have pop up window that is not part of MainWindow.xaml these commands are only grayed out and not functional anymore (cannot be executed). Any advice is highly appreciated!


The way you define the command, you define it for a particular window. If you want to handle the command globally, at the application level, you can use CommandManager.RegisterClassCommandBinding:

First, define you command in a separate static class:

public static class GlobalCommands
{
    public static RoutedUICommand AddCommand1 = new RoutedUICommand("Command ", "command1", typeof(MainWindow));
}

Then, in you window or whatever place you want to put the command logic, register the command handlers:

public partial class MainWindow : Window
{
    static MainWindow()
    {
       CommandManager.RegisterClassCommandBinding(typeof(Window), new CommandBinding(GlobalCommands.AddCommand1, AddCommand1Executed, CanAddExecute));
    }

    private static void AddCommand1Executed(object sender, ExecutedRoutedEventArgs e)
    {
        AddNewItem picker = new AddNewItem();
        picker.ShowDialog();
    }
}

And in your menu style you should change the binding to x:Static:

<Setter Property="Command" Value="{x:Static my:GlobalCommands.AddCommand1}" />


When the command is routed, when checking for command bindings in each active element in the UI, the bindings registered for each element's class will also be checked. By registering the binding here, you can cause every instance of a class to be able to handle the specific command.

So, in the above example, the type Window is used and this will cause the routing to find the command binding in any instance of Window, once the routing reaches that instance in its search for a command binding.

You could instead, for example, restrict the handling to a specific subclass of Window, so that the command will only be bound in an instance of that subclass. Or you can use some other UI element type, so that that the presence of that specific type of element will cause the event to be handled. Just set the owning type for the registered command binding appropriately for your specific needs.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号