将两个命令绑定到一个按钮?

问题描述 投票:0回答:4

我有一个包含两个选项卡的选项卡控件,一个显示正在运行的进程的消息,另一个显示网页!

我有三个按钮(开始、停止和清除) 当我按下启动过程运行并显示消息时。

我需要的是当我按下“开始”按钮时,两个选项卡都会向我显示所需的内容。这意味着我需要两个将两个命令绑定到同一个按钮

你知道如何为一个按钮绑定两个命令吗?

我正在使用 MVVM,我是 MVVM 的新手。

<Button Content="Start" Command="{Binding StartProcess_Command }" Height="25" Width="60" Grid.Row="0" Grid.Column="0" Margin="10"/>
<Button Content="Stop"  Command="{Binding StopProcess_Command}" Height="25" Width="60" Grid.Row="0" Grid.Column="1" Margin="10"/>
<Button Content="Clear" Command="{Binding ClearBtn_Command}" Height="25" Width="60" Grid.Row="0" Grid.Column="2" Margin="10"/>
<telerik:RadTabControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  Grid.Row="1" Grid.ColumnSpan="4" Margin="10">
    <telerik:RadTabItem Header="Maestro" IsSelected="{Binding Path=MaestroSelected}">
        <ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
            <local:WPFBrowser/>
        </ScrollViewer>
    </telerik:RadTabItem>
    <telerik:RadTabItem Header="Messages">
        <Grid Background="LightGray">
            <ScrollViewer VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible">
                <TextBlock TextWrapping="Wrap" Text="{Binding Path=output_process,UpdateSourceTrigger=Default}"/>
            </ScrollViewer>
        </Grid>
    </telerik:RadTabItem>
</telerik:RadTabControl >

这是 WPFBrowser.cs 代码:

         public WPFBrowser()
            {
                ServerString = "localhost"; //defualt value
                PortString = "9999"; //default value
                this.refreshCommand = new Lunch_Maestro.ViewModel.Command(DoRefreshCommand);
                m_WPFBrowser = new WebBrowser()
                {
                    HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
                    VerticalAlignment = System.Windows.VerticalAlignment.Stretch
                };

                m_WPFBrowser.Navigated += WPFBrowser_Navigated;

                this.Content = m_WPFBrowser;
            }

            private void WPFBrowser_Navigated(object sender, System.Windows.Navigation.NavigationEventArgs e)
            {
                this.HideScriptErrors(m_WPFBrowser, true);
            }


            /// <summary>
            /// Found this link with interesting scenerios for script erros...
            /// http://social.msdn.microsoft.com/Forums/vstudio/en-US/4f686de1-8884-4a8d-8ec5-ae4eff8ce6db/new-wpf-webbrowser-how-do-i-suppress-script-errors?forum=wpf
            /// </summary>
            public void HideScriptErrors(WebBrowser wb, bool Hide)
            {
                FieldInfo fiComWebBrowser = typeof(WebBrowser).GetField("_axIWebBrowser2", BindingFlags.Instance | BindingFlags.NonPublic);
                if (fiComWebBrowser == null) return;

                object objComWebBrowser = fiComWebBrowser.GetValue(wb);

                if (objComWebBrowser == null) return;

                objComWebBrowser.GetType().InvokeMember("Silent", BindingFlags.SetProperty, null, objComWebBrowser, new object[] { Hide });

            }


            private void DoRefreshCommand()
            {
                m_WPFBrowser.Navigate(new Uri("http://" + ServerString + ":" + PortString + "/"));
            }

            private bool _maestroSelected;
            public bool MaestroSelected
            {
                get { return _maestroSelected; }
                set
                {
                    _maestroSelected = value;
                    if (_maestroSelected == true)
                        m_WPFBrowser.Navigate(new Uri("http://" + ServerString + ":" + PortString + "/"));
                    OnPropertyChanged("MaestroSelected");
                }
            }

            private readonly WebBrowser m_WPFBrowser;

            private string _serverString;
            public string ServerString
            {
                get { return _serverString; }
                set
                {
                    _serverString = value;
                    OnPropertyChanged("ServerString");
                }
            }

            private string _portString;
            public string PortString
            {
                get { return _portString; }
                set
                {
                    _portString = value;
                    OnPropertyChanged("PortString");
                }
            }

            private Lunch_Maestro.ViewModel.Command refreshCommand;
            public Lunch_Maestro.ViewModel.Command RefreshCommand
            {
                get { return refreshCommand; }
            }
// and Inotify property changes here
wpf mvvm browser command
4个回答
11
投票

你可以像这样调用多个命令:

// xmlns:i="http://schemas.microsoft.com/xaml/behaviors"

<Button>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:InvokeCommandAction Command="{Binding Cmd1}" />
            <i:InvokeCommandAction Command="{Binding Cmd2}" />
            <i:InvokeCommandAction Command="{Binding Cmd3}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

这也将允许您在需要时控制命令执行顺序

PS:你只需要安装

Microsoft.Xaml.Behaviors.Wpf
NuGet包。


8
投票

您想单击一个

Button
并运行两段代码……听起来确实没有那么复杂。使用可用的
RelayCommand
s
之一,问题可以像这样简单地解决:

public ICommand SomeCommand
{
    get { return new ActionCommand(action) => { RunFirstFunction(action); 
        RunSecondFunction(action) }, canExecute => someCondition); }
}

在 XAML 中:

<Button Command="{Binding SomeCommand}" CommandParameter="{Binding SomeObject}">
    Click Me
</Button>

ActionCommand
是我自己的
RelayCommand
形式,但所有
delegate ICommand
实现大致相同,可以以这种方式工作。
CommandParameter
值作为
action
变量进入代码,并传递给两个函数。


3
投票

您可以使用 Prism 框架中的 CompositeCommand。 在您的视图模型中创建一个额外的 CompositeCommand,使用此 CompositeCommand 注册两个普通命令并将按钮绑定到 CompositeCommand。

有关如何使用 CompositeCommands 的信息,请参阅第 130 页的 Prism 文档

您的应用需要引用 Prism 包中包含的 Microsoft.Practices.Prism.dll。


0
投票

另一种方法是使用 WPF,按钮可以轻松地做两件事 - 通过 Click 事件和 Command 事件。限制:只有两件事。优势:使用标准按钮的强大功能,因此您不需要其他 NuGet 包或第三方引用。

在你的 Xaml 中:

<Button Style="{StaticResource CancelButtonStyle}"
        Command="{Binding CancelScenarioCommand}"
        Click="On_Close_Button" />

在你后面的 Xaml.cs 代码中:

private void On_Close_Button(object sender, RoutedEventArgs e)
{
    Close();
}

在您的 ViewModel (VM) 中:

public ICommand CancelScenarioCommand { get; }

public ThisViewModel()
{
   CancelScenarioCommand = new RelayCommand(OnCancelScenario);
}

private void OnCancelScenario()
{
    // do something spectacular
}
© www.soinside.com 2019 - 2024. All rights reserved.