トグルボタンのグループをWPFのラジオボタンのように動作させるにはどうすればよいですか?


122

トグルボタンのように動作するボタンのグループがありますが、同時に選択できるボタンは1つしかありません。また、どのボタンも選択/押下されていない状態である必要があります。

ビヘイビアーは、Photoshopのツールバーのようなもので、ツールの0または1つがいつでも選択されます。

これをWPFに実装する方法はありますか?

回答:


38

最も簡単な方法は、ItemBoxにToggleButtonを使用するようにListBoxをスタイルすることです。

<Style TargetType="{x:Type ListBox}">
    <Setter Property="ListBox.ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <ToggleButton Content="{Binding}" 
                              IsChecked="{Binding IsSelected, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListBoxItem}}}"
                />
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

次に、ListBoxのSelectionModeプロパティを使用して、SingleSelectとMultiSelectを処理できます。


共有していただきありがとうございます!..私は、これは良い習慣であるかどうかを疑問に思っていた...しかし、それは大丈夫のようです
GorillaApe

1
@LeeLouviere:なぜそうしないのか詳しく説明してもらえますか?これは、アイテムテンプレートの使用方法の典型的な例ではありませんか?
またはMapper 2013年

4
表示と動作を混同するため、これは悪い例です。datatemplateを介して表示を変更しますが、リストボックスの動作はありますが、ラジオ/トグルボタンのセットの動作はありません。キーボードの操作が奇妙です。より良い解決策は、ToggleButtonsとしてスタイル設定されたRadioButtonsを持つItemsControlです(他の最高投票数の回答を参照)。
Zarat 2015

なぜ車輪を再発明するのですか?
ウォブル

300

これは私の意見では最も簡単な方法です。

<RadioButton Style="{StaticResource {x:Type ToggleButton}}" />

楽しい!-プリックソー


29
これは断然答えを選ぶべきです。一部のコントローラーにバインドする欠点がないラジオボタンのすべての利点を提供します。私は最初に非表示のラジオボタンセットを分離するためにバインドを試みましたが、不必要なオーバーヘッドがあり、クリックされたすべてのボタンが強調表示されているように見えるが必ずしもチェックされていないというバグに終わりました。
Lee Louviere、2012

16
または、これを要素(たとえばGrid)内のすべてのRadioButtonに適用する必要がある場合は、を使用します<Grid.Resources> <Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}" /> </Grid.Resources>
Roman Starkov

16
この方法の1つの欠点は、チェックされているものをクリックしてもラジオボタンのチェックを外せないことです。
Julien

2
どういうわけかそのようなトグルボタンでカスタムスタイルを使用できますか?
ワンドラ2014年

2
@wondra FrameworkElementに割り当てることができるスタイルは1つだけです。ただし、romkynsソリューションを適応させ、ToggleButtonスタイルから継承することができます。<Style BasedOn="{StaticResource {x:Type ToggleButton}}" x:Key="Blubb" TargetType="RadioButton"><Setter Property="Background" Value="Yellow" /></Style>
Suigi

32
<RadioButton Content="Point" >
    <RadioButton.Template>
        <ControlTemplate>
            <ToggleButton IsChecked="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
                          Content="{Binding Content, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"/>
        </ControlTemplate>
    </RadioButton.Template>
</RadioButton>

それは私のために働きます、楽しんでください!


これは問題ではありません。しかし、ボタンを常に選択する必要があるラジオボタンのように動作させるにはどうすればよいでしょうか。
Karsten

私の回答への私の自身の質問:Uday Kiranによる回答を読んでください:-)
Karsten

これはトグルボタンと同じように機能します。クリックしてチェックし、同じボタンをクリックしてチェックを外します。すべてのRadioButtonを同じグループに入れると、RadioButtonのように機能します。RoKKありがとうございます!!!
ミリ

2
それは良い解決策です。ただし、イベントがある場合。2回呼び出されます。
Khiem-Kim Ho Xuan

コンテンツを追加する場合、単純な文字列の場合、「要素は既に別の要素の子です。」と表示されます。エラー。これを回避する方法はありますか?
Tobias Hoefer 2015

5

VisualTreeHelperの助けを借りて、groupcontrol(Grid、WrapPanel、...)のすべてのToggleButton.IsCheckedをfalseに設定するToggleButtonのClickで常にジェネリックイベントを使用できます。その後、送信者を再確認してください。またはそのようなものの何か。

private void ToggleButton_Click(object sender, RoutedEventArgs e)
    {
        int childAmount = VisualTreeHelper.GetChildrenCount((sender as ToggleButton).Parent);

        ToggleButton tb;
        for (int i = 0; i < childAmount; i++)
        {
            tb = null;
            tb = VisualTreeHelper.GetChild((sender as ToggleButton).Parent, i) as ToggleButton;

            if (tb != null)
                tb.IsChecked = false;
        }

        (sender as ToggleButton).IsChecked = true;
    }

4

ラジオボタンを含むグリッドを配置し、raduiobuttonsのテンプレートのようなボタンを作成できます。プログラムでボタンを切り替えたくない場合は、チェックを外すだけでなく


しかし、ラジオボタンを使用して、すべてのボタンを選択解除する方法はありますか?選択すると、選択を解除する簡単な方法が表示されません。
code-zoop

RadioButtonにはIsCheckedプロパティがあり、必要に応じてコードでfalseに設定できます
Arsen Mkrtchyan

2

あなたも試すことができます System.Windows.Controls.Primitives.ToggleButton

 <ToggleButton Name="btnTest" VerticalAlignment="Top">Test</ToggleButton>

次に、IsCheckedプロパティに対してコードを記述して、ラジオボタン効果を模倣します

 private void btnTest_Checked(object sender, RoutedEventArgs e)
 {
     btn2.IsChecked = false;
     btn3.IsChecked = false;
 }

これはあまり一般的ではなく、再利用できません...たとえば、の内部では使用できませんListBoxItem
ANeves

0

RibbonToggleButtonsでこれを行いましたが、通常のToggleButtonsでも同じかもしれません。

ここからEnumToBooleanConverterを使用して、各ボタンのIsCheckedを「モード」列挙値にバインドしました。RadioButtonを列挙型にバインドする方法は?(ConverterParameterを使用して、このボタンの列挙値を指定します。ボタンごとに1つの列挙値が必要です)

次に、既にチェックされているボタンがチェック解除されないようにするには、各RibbonToggleButtonsのClickイベントのコードビハインドにこれを配置します。

    private void PreventUncheckRibbonToggleButtonOnClick ( object sender, RoutedEventArgs e ) {

        // Prevent unchecking a checked toggle button - so that one always remains checked
        // Cancel the click if you hit an already-checked button

        var button = (RibbonToggleButton)sender;
        if( button.IsChecked != null ) { // Not sure why checked can be null but that's fine, ignore it
            bool notChecked = ( ! (bool)button.IsChecked );
            if( notChecked ){ // I guess this means the click would uncheck it
                button.IsChecked = true; 
            }
        }
    }

0

ジュリアンや私のような人々を助けるため(2分前...)。RadioButtonこのようにして派生できます。

class RadioToggleButton : RadioButton
{
    protected override void OnToggle()
    {
        if (IsChecked == true) IsChecked = IsThreeState ? (bool?)null : (bool?)false;
        else IsChecked = IsChecked.HasValue;
    }
}

その後、Uday Kiranが提案するように使用できます...

<Window x:Class="Sample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Sample"
    Title="MainWindow" Height="600" Width="600">
    <StackPanel>
        <local:RadioToggleButton Content="Button" Style="{StaticResource {x:Type ToggleButton}}" />
    </StackPanel>
</Window>

この方法は、一つだけを許可ToggleButtonするChecked時に、それはまた、オフにすることができます。


0

私は答えのいくつかを取り、いくつかの追加コードを追加しました。これで、1つのトグルボタンのように機能するトグルボタンのさまざまなグループを持つことができます。

<UserControl.Resources>
    <Style x:Key="GroupToggleStyle" TargetType="ToggleButton">
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding GroupName, RelativeSource={RelativeSource Self}}" Value="Group1"/>
                    <Condition Binding="{Binding BooleanProperty}" Value="true"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.Setters>
                    <Setter Property="IsChecked" Value="true"/>
                </MultiDataTrigger.Setters>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</UserControl.Resources>

また、トグルボタンのように見えるラジオボタンのさまざまなグループ:

<Radio Button GroupName="Group1" Style="{StaticResource {x:Type ToggleButton}}">
<Radio Button GroupName="Group1" Style="{StaticResource {x:Type ToggleButton}}">
<Radio Button GroupName="Group2" Style="{StaticResource {x:Type ToggleButton}}">
<Radio Button GroupName="Group3" Style="{StaticResource {x:Type ToggleButton}}">
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.