WPF에서 라디오 버튼처럼 작동하도록 토글 버튼 그룹을 얻는 방법은 무엇입니까?


122

토글 버튼처럼 작동해야하는 버튼 그룹이 있지만 현재 시간에 하나의 버튼 만 선택 / 누를 수있는 라디오 버튼 역할도합니다. 또한 아무 버튼도 선택 / 누르지 않은 상태 여야합니다.

이 동작은 Photoshop 도구 모음과 유사하며 언제든지 도구 중 하나 또는 하나가 선택됩니다!

이것이 WPF에서 어떻게 구현 될 수 있는지 아십니까?

답변:


38

가장 쉬운 방법은 ListBox의 스타일을 지정하여 ItemTemplate에 ToggleButtons를 사용하는 것입니다.

<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 : 왜 안될까요? 항목 템플릿을 사용하는 방법의 대표적인 예가 아닙니까?
OR Mapper

4
디스플레이와 동작을 혼동하기 때문에 나쁜 예입니다. 데이터 템플릿을 통해 디스플레이를 변경하지만 여전히 라디오 / 토글 버튼 세트의 동작이 아닌 목록 상자 의 동작이 있습니다. 키보드 상호 작용이 이상합니다. 더 나은 솔루션은 ToggleButtons로 스타일이 지정된 RadioButtons가있는 ItemsControl입니다 (다른 최고 투표 답변 참조).
Zarat 2015-04-15

바퀴를 재발 명하는 이유는 무엇입니까?
Wobbles

300

제 생각에는 이것이 가장 쉬운 방법입니다.

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

즐겨! -가시 톱


29
이것은 지금까지 선택된 대답이어야합니다. 일부 컨트롤러에 바인딩하는 단점없이 라디오 버튼의 모든 이점을 제공합니다. 처음에는 보이지 않는 라디오 버튼 세트를 분리하기 위해 바인딩을 시도했지만 불필요한 오버 헤드가 있었고 클릭 한 모든 버튼이 강조 표시되었지만 반드시 확인되지 않은 버그가 발생했습니다.
Lee Louviere 2012

16
또는 요소 (예 : a Grid) 내의 모든 RadioButton에이를 적용해야하는 경우 <Grid.Resources> <Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}" /> </Grid.Resources>.
Roman Starkov

16
이 방법의 한 가지 단점은 선택한 버튼을 클릭하여 라디오 버튼을 선택 취소 할 수 없다는 것입니다.
Julien

2
그런 토글 버튼에 어떻게 든 커스텀 스타일을 사용할 수 있습니까?
wondra

2
@wondra FrameworkElement에는 단일 스타일 만 할당 할 수 있습니다. 그러나 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을 같은 그룹에 넣으면 라디오 버튼처럼 작동합니다. RoKK 감사합니다 !!!
mili

2
좋은 해결책입니다. 그러나 이벤트가있을 때. 두 번 호출됩니다.
Khiem-Kim Ho Xuan

간단한 문자열이 아닌 다른 내용을 추가하면 "요소는 이미 다른 요소의 자식입니다."라는 메시지가 표시됩니다. 오류. 이 주위에 방법이 있습니까?
Tobias Hoefer

5

VisualTreeHelper의 도움으로 groupcontrol (Grid, WrapPanel, ...)의 모든 ToggleButton.IsChecked를 false로 설정하는 ToggleButton 클릭시 항상 일반 이벤트를 사용할 수 있습니다. 그런 다음 보낸 사람을 다시 확인하십시오. 또는 그와 비슷한 것.

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

의 RadioButton이의 IsChecked 속성이, 당신은 코드에서 false로 설정할 수 있습니다 때 필요
아르센 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;
 }

이것은 그다지 일반적이지 않고 재사용이 가능하지 않습니다 ... 예를 들어 ListBoxItems 내부에서 사용할 수 없습니다 .
ANeves

0

RibbonToggleButtons에 대해이 작업을 수행했지만 일반 ToggleButtons에도 동일 할 수 있습니다.

여기에서 EnumToBooleanConverter를 사용하여 각 단추에 대한 IsChecked를 "모드"열거 형 값 에 바인딩했습니다. RadioButtons를 열거 형에 바인딩하는 방법은 무엇입니까? (ConverterParameter를 사용하여이 단추에 대한 열거 형 값을 지정합니다. 각 단추에 대해 하나의 열거 형 값이 있어야합니다.)

그런 다음 이미 확인 된 버튼의 선택을 취소하지 않도록 각 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허용하고 UnChecking도 허용합니다.


0

몇 가지 답변을 가져 와서 추가 코드를 추가했습니다. 이제 하나의 토글 버튼처럼 작동하는 다양한 토글 버튼 그룹을 가질 수 있습니다.

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