将按钮绑定到所选项目

时间:2013-07-24 09:00:35

标签: wpf data-binding

我有一个按钮,想要在每次更改标签时更改点击处理程序。我希望用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中是如何工作的。

2 个答案:

答案 0 :(得分:4)

您可以使用Commands实现此目的,您将为每个玩具ICommand TabItem创建ViewModels并绑定Buttons Command属性为Command

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或Control:

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

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

    private void MethodToExecute()
    {

    }
}

<强>的Xaml:

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

答案 1 :(得分:3)

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

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

Click是一个事件,如果你想要你也可以执行事件来命令绑定(将任何事件绑定到viewmodel中的命令),但在你的情况下这不是必需的