WPF'de radyo düğmeleri gibi davranacak bir grup geçiş düğmesi nasıl elde edilir?


122

Geçiş düğmeleri gibi davranması gereken bir grup düğmem var, aynı zamanda aynı anda yalnızca bir düğmenin seçilebildiği / basılabildiği radyo düğmeleri olarak da var. Ayrıca, düğmelerden hiçbirinin seçilmediği / basılmadığı bir duruma sahip olması gerekir.

Davranış, herhangi bir zamanda araçlardan sıfırın veya birinin seçildiği Photoshop araç çubuğu gibi olacaktır!

Bunun WPF'de nasıl uygulanabileceği hakkında bir fikriniz var mı?

Yanıtlar:


38

En kolay yol, bir ListBox'u ItemTemplate için ToggleButtons kullanacak şekilde biçimlendirmektir.

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

Daha sonra SingleSelect ve MultiSelect'i işlemek için ListBox öğesinin SelectionMode özelliğini kullanabilirsiniz.


paylaşım için teşekkürler! Bunun iyi bir uygulama olup olmadığını merak ediyordum ... ama sorun yok gibi görünüyor ..
GorillaApe

1
@LeeLouviere: Neden olmasın ayrıntılara girmek ister misiniz? Bu, öğe şablonunun nasıl kullanılacağına dair en iyi örnek değil mi?
VEYA Eşleyici

4
Bu kötü bir örnek çünkü gösteriyi ve davranışı karıştırıyorsunuz. Görüntüyü veri şablonu aracılığıyla değiştirirsiniz, ancak yine de bir liste kutusunun davranışına sahip olursunuz ve bir radyo / geçiş düğmesinin davranışına sahip değilsiniz . Klavye etkileşimi tuhaf. Daha iyi bir çözüm, ToggleButtons olarak biçimlendirilmiş RadioButtons içeren ItemsControl olacaktır (diğer en yüksek oyu alan yanıta bakın).
Zarat

Neden tekerleği yeniden icat etmelisiniz?
Wobbles

300

Bence bu en kolay yol.

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

Zevk almak! - Pricksaw


29
Bu cevap arayla seçilmelidir. Bazı denetleyicilere bağlanmanın dezavantajları olmadan size bir radyo düğmesinin tüm avantajlarını sunar. İlk önce görünmez radyo düğmesi kümesini ayırmak için bağlamayı denedim, ancak bu gereksiz ek yüke sahipti ve tıklanan tüm düğmelerin vurgulanmış göründüğü ancak mutlaka kontrol edilmediği bir hatayla sonuçlandı.
Lee Louviere

16
Veya, bunu bir eleman (örneğin a Grid) içindeki tüm RadioButton'lara uygulamanız gerekiyorsa , kullanın <Grid.Resources> <Style TargetType="RadioButton" BasedOn="{StaticResource {x:Type ToggleButton}}" /> </Grid.Resources>.
Roman Starkov

16
bu yöntemin bir dezavantajı, işaretlenmiş bir radyo düğmesinin işaretini tıklayarak kaldıramamanızdır.
Julien

2
Böyle bir geçiş düğmesinde bir şekilde özel stil kullanılabilir mi?
wondra

2
@wondra Bir FrameworkElement'e yalnızca tek bir stil atayabilirsiniz. Bununla birlikte, romkyns çözümünü uyarlayabilir ve ToggleButton stilinden miras alabilirsiniz:<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>

benim için çalışıyor, tadını çıkarın!


Sorunun bu olmadığını biliyorum. Ancak düğme, her zaman seçilmesi gereken radyo düğmeleri gibi davranırsa ne yapmalı?
Karsten

Cevabıma kendi sorum: Uday Kiran'ın cevabını oku :-)
Karsten

Güzel, bu, Geçiş düğmesiyle AYNI davranır. Kontrol etmek için tıklayın ve işareti kaldırmak için aynı düğmeyi tıklayın. ve tüm RadioButton'ları aynı gruba koyduğumda, Radyo düğmeleri gibi davranıyor. Teşekkürler RoKK !!!
mili

2
Bu iyi bir çözüm. Ancak, bir etkinliğimiz olduğunda. iki kez aranacak.
Khiem-Kim Ho Xuan

Basit bir dizeden başka bir içerik ekleme varsa, "Öğe zaten başka bir öğenin alt öğesi" alırım. hata. Bunun etrafında bir yol var mı?
Tobias Hoefer

5

VisualTreeHelper yardımıyla bir grup kontrolünde (Grid, WrapPanel, ...) tüm ToggleButton.IsChecked öğelerini false olarak ayarlayan ToggleButton Tıklaması üzerinde her zaman genel bir olay kullanabilirsiniz; sonra göndereni yeniden kontrol edin. Ya da buna benzer bir şey.

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

içine radyo düğmeleri olan ızgara koyabilir ve radui düğmeleri için şablon benzeri düğme oluşturabilirsiniz. sadece programla kaldırmaktan ziyade düğmelerin değiştirilmesini istemiyorsanız kontrol edin


Ancak radyo düğmelerini kullanarak tüm düğmelerin seçimini kaldırmanın bir yolu var mı? Seçildikten sonra, seçimi kaldırmanın kolay bir yolunu göremiyorum!
code-zoop

RadioButton'da IsChecked özelliği var, ihtiyacınız olduğunda bunu kodda yanlış olarak ayarlayabilirsiniz
Arsen Mkrtchyan

2

Ayrıca deneyebilirsin System.Windows.Controls.Primitives.ToggleButton

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

Ardından IsChecked, radiobutton efektini taklit etmek için özelliğe karşı kod yazın

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

Bu çok genel ve tekrar kullanılabilir değildir ... örneğin, ListBoxItems içinde kullanılamaz .
ANeves

0

Bunu RibbonToggleButtons için yaptım, ancak normal ToggleButtons için de aynı olabilir.

Her düğme için IsChecked'i EnumToBooleanConverter kullanarak buradan bir "mod" enum değerine bağladım RadioButtons bir numaralandırmaya nasıl bağlanır?(ConverterParameter'ı kullanarak bu düğme için enum değerini belirtin. Her düğme için bir enum değeriniz olmalıdır)

Ardından, önceden işaretlenmiş bir düğmenin işaretinin kaldırılmasını önlemek için, bunu ŞeritToggleButton'ların her biri için Click olayı için kodunuzun arkasına koyun:

    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

Julian ve benim gibi insanlara yardım etmek için (iki dakika önce ...). Bunun gibi şeylerden türetebilirsiniz RadioButton.

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

O halde Uday Kiran'ın önerdiği gibi kullanabilirsiniz ...

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

Bu yöntem aynı anda yalnızca birinin ToggleButtonolmasına Checkedizin verir ve ayrıca Kontrol Kaldırmaya da izin verir.


0

Cevaplardan birkaç parça aldım ve fazladan kod ekledim. Artık, tek bir geçiş düğmesi gibi davranan farklı geçiş düğmesi gruplarına sahip olabilirsiniz:

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

Ve geçiş düğmelerine benzeyen farklı radyo düğmesi grupları:

<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}}">
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.