Impossible de lier isChecked sur le bouton radio avec ControlTemplate personnalisé

StackOverflow https://stackoverflow.com/questions/5381786

  •  28-10-2019
  •  | 
  •  

Question

J'utilise un contrôle RadioButton personnalisé avec un ToggleButton comme modèle de contrôle. Voici ce que les regards de XAML comme:

    <RadioButton.Template>
        <ControlTemplate>
            <ToggleButton x:Name="tb" IsChecked="{Binding IsChecked, Mode=TwoWay, 
                                RelativeSource={RelativeSource TemplatedParent}}" 
                                      Content="{TemplateBinding RadioButton.Content}"
                          PreviewMouseDown="tb_PreviewMouseDown">
            </ToggleButton>
        </ControlTemplate>
    </RadioButton.Template>

Il a été fonctionne bien, sauf lorsque je tente de mettre la propriété soit programatically IsChecked d'un bouton, ou faire une reliure avec elle. Ensuite, le bouton qui doit être vérifié visuellement ne répond pas - il ne semble pas être pressé, et la souris Aero sur l'effet ne semble pas. Le gestionnaire d'événements clicked fonctionne toujours, et la propriété IsChecked des deux RadioButton et le bouton à bascule du ControlTemplate sont vraies quand j'examine leurs valeurs. Amy je faisais quelque chose de mal avec la liaison? Toutes les idées?

Voici un exemple de la façon dont je l'utilise dans l'application:

<local:RadioToggleButton Content="1Hr" GroupName="Interval" x:Name="oneHrBtn" 
IsChecked="{BindingPath=oneHrBtnIsChecked, Mode=TwoWay}" Margin="2 5 3 5" 
IsEnabled="{Binding Path=oneHrBtnIsEnabled, Mode=TwoWay}"/>
Était-ce utile?

La solution

Donc, la question de mon contrôle RadioToggleButton sur mesure a été causé par quelque chose de très étrange en effet. Je vais décrire ma solution ci-dessous, pas parce que j'attends quelqu'un d'autre à courir sur ce problème particulier, mais comme un exemple d'une solution qui semble sans rapport avec le problème.

Il y avait une fixation sur la propriété IsEnabled du GroupBox contenant le groupe de boutons. Cette liaison semble fonctionner correctement, activer et désactiver tous les contrôles internes, le cas échéant. Mais dès que je l'ai enlevé cette liaison, le problème que je décrit ci-dessus a disparu. Ce n'est pas idéal, mais j'ai décidé que j'avais passé trop de temps sur cette question, donc je lié les propriétés isEnabled des contrôles individuels à la même propriété que le GroupBox avait été lié, et maintenant au moins je le I comportement voulu.

Autres conseils

Qu'est-ce que vous avez est très étrange. La classe RadioButton dérive de ToggleButton. Donc, en réalité vous mettez un bouton dans un bouton. Est-ce que vous essayez simplement de faire le look RadioButton comme un ToggleButton? Si oui, pourquoi ne pas utiliser directement ToggleButton?

Si vous voulez faire le look RadioButton comme un ToggleButton pour que vous puissiez utiliser la fonction GroupName, alors vous devez copier le modèle de contrôle ToggleButton et de l'utilisation que (non intégrer un ToggleButton dans le modèle de contrôle).

Vous pouvez obtenir les modèles par défaut de ici . Ensuite, la recherche pour le style ToggleButton et le copier est ControlTemplate.

EDIT:

L'exemple suivant montre comment cela peut être fait. Vous avez juste besoin d'ajouter une référence à PresentationFramework.Aero.

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>

        <LinearGradientBrush x:Key="ButtonNormalBackground" StartPoint="0,0" EndPoint="0,1">
            <LinearGradientBrush.GradientStops>
                <GradientStop Color="#F3F3F3" Offset="0" />
                <GradientStop Color="#EBEBEB" Offset="0.5" />
                <GradientStop Color="#DDDDDD" Offset="0.5" />
                <GradientStop Color="#CDCDCD" Offset="1" />
            </LinearGradientBrush.GradientStops>
        </LinearGradientBrush>
        <SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070" />

            <Style x:Key="ButtonFocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" StrokeThickness="1" Stroke="Black" StrokeDashArray="1 2" SnapsToDevicePixels="true" />
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

        <Style x:Key="{x:Type RadioButton}" TargetType="{x:Type RadioButton}">
            <Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}" />
            <Setter Property="Background" Value="{StaticResource ButtonNormalBackground}" />
            <Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}" />
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
            <Setter Property="HorizontalContentAlignment" Value="Center" />
            <Setter Property="VerticalContentAlignment" Value="Center" />
            <Setter Property="Padding" Value="1" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type RadioButton}">
                        <theme:ButtonChrome Name="Chrome" Background="{TemplateBinding Background}"
                                BorderBrush="{TemplateBinding BorderBrush}" RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
                                RenderMouseOver="{TemplateBinding IsMouseOver}" RenderPressed="{TemplateBinding IsPressed}"
                                SnapsToDevicePixels="true">
                            <ContentPresenter Margin="{TemplateBinding Padding}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                        </theme:ButtonChrome>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsKeyboardFocused" Value="true">
                                <Setter TargetName="Chrome" Property="RenderDefaulted" Value="true" />
                            </Trigger>
                            <Trigger Property="ToggleButton.IsChecked" Value="true">
                                <Setter TargetName="Chrome" Property="RenderPressed" Value="true" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Foreground" Value="#ADADAD" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <StackPanel>
        <RadioButton GroupName="TestGroup">Option 1</RadioButton>
        <RadioButton GroupName="TestGroup">Option 2</RadioButton>
    </StackPanel>
</Window>

Si tout ce que vous voulez est un RadioButton qui ressemble à un ToggleButton, vous pouvez réellement se référer implicitement au style de ToggleButton en tant que ressource statique par son type:

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

Cela semble fonctionner parce RadioButton est descendu de ToggleButton. Donc, vous ne pouvez pas, par exemple, l'utilisation {StaticResource {x:Type ComboBox}}.

Je ne suis pas en mesure de traquer toute la documentation pour l'utilisation d'un x:Type comme une ressource pour Style; Je serais intéressé de le voir, si quelqu'un là-bas sait où chercher.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top