3

問題はこれです。3つのトグルボタンがあり、コマンドを使用して一度に1つだけチェックしたいとします。1つのボタンをオンにすると、他のボタンを無効にする必要があります。(ラジオボタンは使いたくない)。だから私はこの単純なコードを作成しましたが、奇妙なことに、チェックされたボタンがクリックされたときにコマンド実行が実行されません(メッセージボックスは表示されません)。

<Window x:Class="ToggleButtonsProblem.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<StackPanel>
    <ToggleButton Command="{Binding ToggleCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">A</ToggleButton>
    <ToggleButton Command="{Binding ToggleCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">B</ToggleButton>
    <ToggleButton Command="{Binding ToggleCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">C</ToggleButton>
</StackPanel>

using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Controls.Primitives;

namespace ToggleButtonsProblem {
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window {
    public MainWindow() {
        InitializeComponent();
        this.DataContext = new ViewModel();
    }
}

public class ViewModel {
    public static ICommand ToggleCommand { get { return new ToggleCommand(); } }
}

public class ToggleCommand : ICommand {
    public static bool isSomeChecked = false;
    public static ToggleButton currentCheckedButton;

    public bool CanExecute(object parameter) {
        if (currentCheckedButton == null) return true;
        return (parameter as ToggleButton).IsChecked == true;
    }

    public event EventHandler CanExecuteChanged {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    public void Execute(object parameter) {
        currentCheckedButton = null;
        ToggleButton button = parameter as ToggleButton;
        MessageBox.Show(button.IsChecked.ToString());
        if (button.IsChecked == true) {
            currentCheckedButton = button;
        }
        else {                
            currentCheckedButton = null;
        }
    }
}

}

4

2 に答える 2

1

コマンドは、ボタンが押されたときにのみ実行されます。ToggleButtonのUncheckedイベントをフックする必要があります。たとえば、次のようになります。

<ToggleButton Command="{Binding ToggleCommand}" Unchecked="ToggleButton_Unchecked" CommandParameter="{Binding RelativeSource={RelativeSource Self}}">A</ToggleButton>

そして、コードビハインドクラスにメソッドハンドラーを追加します。

public void ToggleButton_Unchecked(object sender, RoutedEventArgs e) {
    (sender as ToggleButton).Command.Execute(sender);
}

これは機能するはずです。おそらく、ToggleCommandクラスの一部として、メソッドハンドラーを追加するためのより良い方法を見つけることができます。

編集:次のようにCanExecute()メソッドを実装してみてください:

public bool CanExecute(object parameter) {            
    if (currentCheckedButton == null) return true;
    return currentCheckedButton == parameter;
}

私にとってはうまくいきます。これが問題の原因だと思います。ボタンをクリック(チェックを外す)すると、IsCheckedがfalseに変更されます。次に、WPFはExecute()メソッドを呼び出そうとしますが、いつものように、最初にCanExecute()を呼び出します。ただし、チェック状態がすでに変更されているため、CanExecute()はfalseを返し、Execute()メソッドは呼び出されません。

于 2012-12-25T15:58:12.500 に答える
0

ToggleCommandは静的であってはなりません。コマンドをプロパティとして定義してみてください。

于 2012-12-25T14:10:06.667 に答える