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でこれを実現できます。 ICommandfor each の toyを作成し、プロパティをそれに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()
    {

    }
}

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>
于 2013-07-24T09:19:46.273 に答える
3

次のように、ボタンの Command プロパティを WPF のコマンドにバインドする必要があります。

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

クリックはイベントです。必要に応じて、イベントからコマンドへのバインド (ビューモデルで任意のイベントをコマンドにバインド) を実行することもできますが、この場合は必要ありません。

于 2013-07-24T09:09:00.843 に答える