samedi 15 juin 2019

Slider-Button -> CheckBox using Controltemplate with Slider - Click doesn't change ischecked state

im trying to make a sliding on-off button controltemplate for a CheckBox control. I decided to use the Slider control since it already delivers the basic functionality needed. What i did so far is creating the template with the slider in it and binding the slider value to the ischecked property of the TemplatedParent using a ValueConverter.

So far the ControlTemplate is working as expected when dragging the slider with the mouse, or clicking on the track. However if i click on the Thumb i want the Slider to change value too, like you would expect from a normal Checkbox.

If i disable HitTestVisibility of the Slider and put a Transparent rectangle over it the Control works like a normal Checkbox - Clicking toggles the IsChecked state. But with that i lose the feature of sliding it into the desired state.

I have also tried using DataTriggers to set the Slider to the IsChecked state instead of DataBinding it:

<ControlTemplate.Triggers>
    <Setter TargetName="ControlSlider" Property="Value" Value="0"/>
    <Trigger Property="IsChecked" Value="True">
        <Setter TargetName="ControlSlider" Property="Value" Value="1"/>
    </Trigger>
</ControlTemplate.Triggers>

This did work with the "No HitTestVisibility" approach mentioned above, but it doesn't do anything when i use the slider functionality.

This is my Template and the Checkbox:

<ControlTemplate x:Key="OnOffSlider" TargetType="{x:Type CheckBox}">
    <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
        <Grid Width="Auto" VerticalAlignment="Center">
            <Slider x:Name="ControlSlider" Maximum="1" Minimum="0" IsEnabled="True" IsHitTestVisible="True" Width="30" TickFrequency="1" IsSnapToTickEnabled="True" Value="{Binding IsChecked, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}">
            </Slider>
        </Grid>
        <ContentPresenter Margin="10,0,0,0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" ContentTemplate="{TemplateBinding ContentTemplate}" RecognizesAccessKey="True" VerticalAlignment="Center" HorizontalAlignment="Center"/>
    </StackPanel>
</ControlTemplate>

<CheckBox>
    <CheckBox.Style>
        <Style TargetType="CheckBox">
            <Setter Property="Template" Value="{StaticResource OnOffSlider}"/>
        </Style>
    </CheckBox.Style>
</CheckBox>

And the ValueConverter:

public class BooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool)
        {
            return ((bool)value) ? 1 : 0;
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is double)
        {
            return ((double)value >= 0.5) ? true : false;
        }
        return null;
    }
}

I want the button to act as a slider with only to states (0 and 1) when dragging the thumb but toggle its state whenever i just click on it. Is this possible in xaml only. When yes, how would i make sure the Click event is changin the state properly?




Aucun commentaire:

Enregistrer un commentaire