2

我有一个按钮,并且每次更改选项卡时都想更改单击处理程序。我希望通过 Binding 来执行此操作。

<Window x:Class="BWCRenameUtility.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vpan="clr-namespace:BWCRenameUtility.View.VersionPanels"
        Title="MainWindow" Height="526" Width="525">
    <Grid>
        <DockPanel>
            <TextBlock Text="Foo" DockPanel.Dock="Top" TextWrapping="Wrap" Padding="10" />
            <Grid DockPanel.Dock="Bottom">
                <!-- This is not correct, how do I perform this binding correct? -->
                <Button Content="Export..." HorizontalAlignment="Right" Margin="10" Click="{Binding SelectedItem.Content.PerformExport,ElementName=tabcontrol}" /> 
            </Grid>
            <TabControl Name="tabcontrol">
                <TabItem Header="1.2.5">
                    <vpan:VersionPanel1_2_5/>
                </TabItem>
                <TabItem Header="1.2.8">
                    <vpan:VersionPanel1_2_8/> <!-- These can be of the same Type by inheritance -->
                </TabItem>
            </TabControl>
        </DockPanel>
    </Grid>
</Window>

如您所见,Button.Click 未正确绑定,我想知道它在 WPF 中是如何工作的。

4

2 回答 2

4

您可以使用Commands来实现这一点,您将为ICommand每个玩具创建一个并将属性TabItem ViewModels绑定到该玩具Buttons CommandCommand

RelayCommand是处理此类事情的一种非常常见的方法,可以在整个应用程序中使用

中继命令:

   public class RelayCommand : ICommand
   {
       #region Fields 

       readonly Action<object> _execute; 
       readonly Predicate<object> _canExecute; 

       #endregion 

       #region Constructors 

       /// <summary>
       /// Initializes a new instance of the <see cref="RelayCommand"/> class.
       /// </summary>
       /// <param name="execute">The execute.</param>
       public RelayCommand(Action<object> execute) : this(execute, null) { }

       /// <summary>
       /// Initializes a new instance of the <see cref="RelayCommand"/> class.
       /// </summary>
       /// <param name="execute">The action to execute.</param>
       /// <param name="canExecute">The can execute.</param>
       /// <exception cref="System.ArgumentNullException">execute</exception>
       public RelayCommand(Action<object> execute, Predicate<object> canExecute) 
       { 
           if (execute == null)
               throw new ArgumentNullException("execute");

           _execute = execute;
           _canExecute = canExecute;
       } 

       #endregion 

       #region ICommand Members 

       /// <summary>
       /// Defines the method that determines whether the command can execute in its current state.
       /// </summary>
       /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
       /// <returns>
       /// true if this command can be executed; otherwise, false.
       /// </returns>
       [DebuggerStepThrough]
       public bool CanExecute(object parameter)
       { 
           return _canExecute == null ? true : _canExecute(parameter);
       }

       /// <summary>
       /// Occurs when changes occur that affect whether or not the command should execute.
       /// </summary>
       public event EventHandler CanExecuteChanged 
       { 
           add { CommandManager.RequerySuggested += value; } 
           remove { CommandManager.RequerySuggested -= value; } 
       }

       /// <summary>
       /// Defines the method to be called when the command is invoked.
       /// </summary>
       /// <param name="parameter">Data used by the command.  If the command does not require data to be passed, this object can be set to null.</param>
       public void Execute(object parameter)
       {
           _execute(parameter); 
       } 

       #endregion 
   }


您将在您的应用程序中以下列方式使用

ViewModel 或控件:

public class VersionPanel1_2_8 : VersionPanel
{
    public ICommand MyCommand { get; internal set; }

    public VersionPanel1_2_8()
    {
          MyCommand = new RelayCommand(x => MethodToExecute());
    }

    private void MethodToExecute()
    {

    }
}

xml:

<Window x:Class="BWCRenameUtility.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vpan="clr-namespace:BWCRenameUtility.View.VersionPanels"
        Title="MainWindow" Height="526" Width="525">
    <Grid>
        <DockPanel>
            <TextBlock Text="Foo" DockPanel.Dock="Top" TextWrapping="Wrap" Padding="10" />
            <Grid DockPanel.Dock="Bottom">
                <!-- This is not correct, how do I perform this binding correct? -->
                <Button Content="Export..." HorizontalAlignment="Right" Margin="10" Command="{Binding SelectedItem.Content.MyCommand,ElementName=tabcontrol}" /> 
            </Grid>
            <TabControl Name="tabcontrol">
                <TabItem Header="1.2.5">
                    <vpan:VersionPanel1_2_5/>
                </TabItem>
                <TabItem Header="1.2.8">
                    <vpan:VersionPanel1_2_8/> <!-- These can be of the same Type by inheritance -->
                </TabItem>
            </TabControl>
        </DockPanel>
    </Grid>
</Window>
于 2013-07-24T09:19:46.273 回答
3

您需要将 Button 的 Command 属性绑定到 WPF 中的命令,例如,

Command="{Binding SelectedItem.Content.PerformExport, ElementName=tabcontrol}" 

单击是一个事件,如果您愿意,您还可以执行事件到命令绑定(将任何事件绑定到视图模型中的命令),但是在您的情况下这不是必需的

于 2013-07-24T09:09:00.843 回答