【问题标题】:How to access command from MainWindow level in another Window?如何在另一个窗口中从 MainWindow 级别访问命令?
【发布时间】:2011-06-24 11:12:06
【问题描述】:

我正在尝试在另一个窗口中访问 MainWindow.xaml 中定义的命令。我只能得到这些命令的灰色标题。我想知道应该做什么才能获得完全访问权限。

命令示例:

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();
    }

我通过数据绑定以样式访问这些命令:

<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>

这些命令在通过框架加载到 MainWindow.xaml 的页面中工作。但是,如果我有不属于 MainWindow.xaml 的弹出窗口,这些命令只会显示为灰色并且不再起作用(无法执行)。任何建议都非常感谢!

【问题讨论】:

    标签: wpf wpf-controls binding


    【解决方案1】:

    定义命令的方式是为特定窗口定义它。如果要全局处理命令,在应用程序级别,可以使用CommandManager.RegisterClassCommandBinding

    首先,在一个单独的静态类中定义你的命令:

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

    然后,在你的窗口或任何你想放置命令逻辑的地方,注册命令处理程序:

    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();
        }
    }
    

    在您的菜单样式中,您应该将绑定更改为x:Static

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


    当命令被路由时,当检查 UI 中每个活动元素中的命令绑定时,也会检查为每个元素的类注册的绑定。通过在此处注册绑定,您可以使类的每个实例都能够处理特定的命令。

    因此,在上面的示例中,使用了 Window 类型,这将导致路由在 Windowany 实例中找到命令绑定,一旦路由到达该实例它搜索命令绑定。

    例如,您可以将处理限制为Window 的特定子类,以便命令仅绑定在该子类的实例中。或者您可以使用其他一些 UI 元素类型,以便该特定类型元素的存在将导致事件被处理。只需根据您的特定需求适当地为已注册的命令绑定设置拥有类型。

    【讨论】:

    • 感谢您的提示。我添加了带有数据绑定的菜单样式。请查看我编辑的问题。我想知道您的技术是否适用于我的情况。再次感谢您!
    • 查看我的更新。您应该使用 x:Static 扩展名绑定命令。
    • 我用你的技术让它工作了。再次感谢您的提示。如果我可以使用公共 MainWindow () 定义而不是您在示例中建议的静态 MainWindow(),我只有一个问题。这会导致任何问题吗?我无法在我的解决方案中改变它,因为我还有其他事情要做。请告诉我。谢谢!
    • 只要您的窗口在应用程序生命周期中创建一次,您就可以使用“public MainWindow ()”。否则处理程序将被多次注册。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-31
    • 2018-10-24
    • 2019-06-13
    • 1970-01-01
    相关资源
    最近更新 更多