Slider-Button -> CheckBox с использованием Controltemplate с Slider - щелчок не меняет проверенное состояние - PullRequest
1 голос
/ 16 июня 2019

Я пытаюсь создать скользящую кнопку включения-выключения для шаблона элемента управления CheckBox.Я решил использовать элемент управления Slider, поскольку он уже обеспечивает базовую необходимую функциональность.На данный момент я создал шаблон с ползунком в нем и связал значение ползунка со свойством ischecked для TemplatedParent, используя ValueConverter.

Пока что ControlTemplate работает, как и ожидалось, при перетаскивании ползунка с помощьюмыши или щелкнув по треку.Однако, если я нажимаю на большой палец, я хочу, чтобы ползунок тоже изменил значение, как и следовало ожидать от обычного флажка.

Если я отключил HitTestVisibility ползунка и поместил прозрачный прямоугольник поверх него, элемент управления работает какнормальный флажок - нажатие переключает состояние IsChecked.Но с этим я теряю возможность сдвинуть его в нужное состояние.

Я также пытался использовать DataTriggers, чтобы установить ползунок в состояние IsChecked вместо привязки данных:

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

Этоработал с подходом «Нет HitTestVisibility», упомянутым выше, но он ничего не делает, когда я использую функцию ползунка.

Это мой шаблон и флажок:

<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, Converter={StaticResource BooleanConverter}}">
            </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>

И 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;
    }
}

Я хочу, чтобы кнопка выполняла функцию ползунка только с состояниями (0 и 1) при перетаскивании большого пальца, но переключала ее состояние всякий раз, когда я просто нажимала на нее.Это возможно только в xaml.Если да, как я могу убедиться, что событие Click меняет свое состояние должным образом?

1 Ответ

0 голосов
/ 16 июня 2019

Если вы собираетесь создать вид управления переключателем с помощью флажка, у меня есть простое решение для этого. Может быть, это может помочь вам.

Я использовал анимацию для перемещения положения флажка (большой палец) вправо / влево, когда отмечен / не отмечен.

Вот мой измененный стиль для флажка.

<Style x:Key="CheckBoxStyle" TargetType="{x:Type CheckBox}">
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Background" Value="Lavender"/>
            <Setter Property="MinWidth" Value="40" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type CheckBox}">

                        <ControlTemplate.Resources>
                            <Storyboard x:Key="OnChecking">
                                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Thumb"
                                                           Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)">
                                    <SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="22"/>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                            <Storyboard x:Key="OnUnchecking">
                                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="Thumb"
                                                           Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(TranslateTransform.X)">
                                    <SplineDoubleKeyFrame KeyTime="00:00:00.6000000" Value="0"/>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </ControlTemplate.Resources>

                        <Grid MinWidth="{TemplateBinding MinWidth}">
                            <Border Margin="1,0,1,0" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="3" Height="6.4" BorderBrush="Gray"
                                Background="Transparent" x:Name="RangeBorder" />

                            <Ellipse x:Name="Thumb" Width="16" Height="16" Fill="{TemplateBinding Background}" StrokeThickness="1" HorizontalAlignment="Left">
                                <Ellipse.RenderTransform>
                                    <TransformGroup>
                                        <TranslateTransform X="0" Y="0"/>
                                    </TransformGroup>
                                </Ellipse.RenderTransform>
                            </Ellipse>
                        </Grid>


                        <ControlTemplate.Triggers>
                            <!--You can modify your own style changes here-->

                            <Trigger Property="IsChecked" Value="True">
                                <Setter TargetName="Thumb" Property="Fill" Value="Brown"/>
                                <Setter TargetName="RangeBorder" Property="BorderBrush" Value="DarkGray"/>
                                <Trigger.ExitActions>
                                    <BeginStoryboard Storyboard="{StaticResource OnUnchecking}" x:Name="OnUnchecking_BeginStoryboard"/>
                                </Trigger.ExitActions>
                                <Trigger.EnterActions>
                                    <BeginStoryboard Storyboard="{StaticResource OnChecking}" x:Name="OnChecking_BeginStoryboard"/>
                                </Trigger.EnterActions>
                            </Trigger>

                            <Trigger Property="IsChecked" Value="False">
                                <Setter TargetName="Thumb" Property="Stroke" Value="LightGray"/>
                            </Trigger>

                            <Trigger Property="IsChecked" Value="{x:Null}">
                                <Setter Property="Opacity" Value="0.5" />
                            </Trigger>

                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="Opacity" Value="0.5" />
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

И в моем Окне, где я использую вышеупомянутый стиль, похоже,

<CheckBox Style="{StaticResource CheckBoxStyle}" Width="40" Height="40"/>

Примечание: - Вы можете изменять цвета, высоту и ширину в соответствии с вашими требованиями.

Надеюсь, это поможет, если нет, прокомментируйте ваши дальнейшие проблемы.

...