Как заставить группу переключателей действовать как переключатели в WPF? - PullRequest
113 голосов
/ 02 марта 2010

У меня есть группа кнопок, которые должны действовать как кнопки переключения, но также как переключатели, где в текущий момент времени можно выбрать / нажать только одну кнопку. Также необходимо иметь состояние, когда ни одна из кнопок не выбрана / нажата.

Поведение будет похоже на панель инструментов Photoshop, где в любой момент выбирается ноль или один из инструментов!

Есть идеи, как это можно реализовать в WPF?

Ответы [ 10 ]

280 голосов
/ 13 марта 2011

На мой взгляд, это самый простой способ.

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

Наслаждайтесь! - Pricksaw

38 голосов
/ 02 марта 2010

Самый простой способ - это оформить ListBox, используя ToggleButtons для его ItemTemplate

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

Затем вы можете использовать свойство SelectionMode ListBox для обработки SingleSelect против MultiSelect.

28 голосов
/ 04 марта 2011
<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>

это работает для меня, наслаждайтесь!

5 голосов
/ 25 августа 2010

вы всегда можете использовать универсальное событие в Click of ToggleButton, которое устанавливает все ToggleButton.IsChecked в groupcontrol (Grid, WrapPanel, ...) в false с помощью VisualTreeHelper; затем перепроверьте отправителя. Или что-то в этом роде.

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 голосов
/ 02 марта 2010

Вы можете поместить сетку с радиокнопками в нее, и создать кнопку, похожую на шаблон для радужных кнопок. чем просто программно удалить проверку, если вы не хотите, чтобы кнопки переключались

3 голосов
/ 04 ноября 2010

Эй, я действительно разработал решение для этого. Вы можете переопределить шаблон управления для радиокнопок и разместить кнопки вниз. У меня есть реализованное решение в библиотеке с открытым исходным кодом здесь:

http://code.google.com/p/phoenix-control-library/

Вы можете получить работающее решение для готового использования ИЛИ взглянуть на исходный код.

Наслаждайтесь.

3 голосов
/ 02 марта 2010

Вы также можете попробовать 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;
 }
0 голосов
/ 09 ноября 2018

Я взял несколько частей ответов и добавил дополнительный код. Теперь вы можете иметь разные группы кнопок переключения, которые действуют как одна кнопка переключения:

<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}}">
0 голосов
/ 14 ноября 2017

Чтобы помочь таким людям, как Джулиан и я (две минуты назад ...). Вы можете получить из RadioButton, как это.

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

Затем вы можете использовать его, как предложил Удай Киран ...

<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 голосов
/ 20 января 2015

Я сделал это для RibbonToggleButtons, но, может быть, то же самое для обычных ToggleButtons.

Я связал IsChecked для каждой кнопки со значением перечисления «mode», используя EnumToBooleanConverter, отсюда Как связать RadioButtonsenum? (Укажите значение enum для этой кнопки с помощью ConverterParameter. У вас должно быть одно значение enum для каждой кнопки)

Затем, чтобы не снимать флажок с кнопки, которая уже отмечена, вставьте ее в свой коддля события Click для каждого из RibbonToggleButtons:

    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; 
            }
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...