【问题标题】:In Xaml, how can I bind the Thumb of a slider to one of the multiple ControlTemplate?在 Xaml 中,如何将滑块的 Thumb 绑定到多个 ControlTemplate 之一?
【发布时间】:2019-01-11 09:28:37
【问题描述】:

我正在尝试在 WPF 中创建一个可编辑的滑块,我需要将 ControlTemplate 与不起作用的滑块拇指的模板绑定。

我有 2 个 ControlTemplate 和一个滑块。应根据控件模板的选择显示滑块的 Thumb。

<ControlTemplate x:Uid="ControlTemplate_3" x:Key="StaticThumbTemplate" TargetType="{x:Type Thumb}">
        <Border x:Uid="Border_3" Margin="1" BorderBrush="Gray" BorderThickness="1" Background="#EEEEEE" MinWidth="30" MaxWidth="50">
                <TextBlock x:Uid="TextBlock_3" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="2,0,2,0"

                Text="{Binding Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Slider}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

        </Border>
</ControlTemplate>

 <ControlTemplate x:Uid="ControlTemplate_4" x:Key="EditThumbTemplate" TargetType="{x:Type Thumb}">
         <TextBox x:Uid="PART_Edit" Padding="2,0,2,0" x:Name="PART_Edit" MinWidth="30" VerticalAlignment="Center" LostFocus="PART_Edit_LostFocus"

                 Text="{Binding Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Slider}, Mode=TwoWay}" />

 </ControlTemplate>

    <Style x:Uid="Style_3" x:Key="ThumbStyle" TargetType="{x:Type Thumb}">
    <Setter x:Uid="Setter_3" Property="Template" Value="{StaticResource StaticThumbTemplate}"/>
    <Style.Triggers>
    <DataTrigger Binding="{Binding IsTyping, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Slider}}" Value="True">
    <Setter x:Uid="Setter_4" Property="Template" Value="{StaticResource EditThumbTemplate}"/>
</DataTrigger>
</Style.Triggers>
</Style>

如果属性IsTyping 从真/假更改,则应显示相应的 ControlTemplate。目前只有Static Thumb Template ControlTemplate 一直在列出。

[更新 1] Slider.xaml的完整代码:

<Slider x:Class="SliderTest.Slider"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:SliderTest"
         mc:Ignorable="d" 
         d:DesignHeight="450" d:DesignWidth="800">
<Slider.Resources>
    <!-- TODO: Focus highlight! -->

    <Style x:Uid="Style_1" x:Key="SliderLeftStyle" TargetType="{x:Type RepeatButton}">
        <Setter x:Uid="Setter_1" Property="Template">
            <Setter.Value>
                <ControlTemplate x:Uid="ControlTemplate_1" TargetType="{x:Type RepeatButton}">
                    <Border x:Uid="Border_1" Background="Transparent">
                        <TextBlock x:Uid="TextBlock_1" Margin="2" HorizontalAlignment="Left" VerticalAlignment="Center" Text="{Binding MinStr, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Slider}}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <Style x:Uid="Style_2" x:Key="SliderRightStyle" TargetType="{x:Type RepeatButton}">
        <Setter x:Uid="Setter_2" Property="Template">
            <Setter.Value>
                <ControlTemplate x:Uid="ControlTemplate_2" TargetType="{x:Type RepeatButton}">
                    <Border x:Uid="Border_2" Background="Transparent">
                        <TextBlock x:Uid="TextBlock_2" Margin="2" HorizontalAlignment="Right" VerticalAlignment="Center" Text="{Binding MaxStr, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Slider}}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <ControlTemplate x:Uid="ControlTemplate_3" x:Key="StaticThumbTemplate" TargetType="{x:Type Thumb}">
        <Border x:Uid="Border_3" Margin="1" BorderBrush="Gray" BorderThickness="1" Background="#EEEEEE" MinWidth="30" MaxWidth="50">
            <TextBlock x:Uid="TextBlock_3" HorizontalAlignment="Center" VerticalAlignment="Center" Padding="2,0,2,0"
                       Text="{Binding Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Slider}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                       />
        </Border>
    </ControlTemplate>

    <ControlTemplate x:Uid="ControlTemplate_4" x:Key="EditThumbTemplate" TargetType="{x:Type Thumb}">
        <TextBox x:Uid="PART_Edit" Padding="2,0,2,0" x:Name="PART_Edit" MinWidth="30" VerticalAlignment="Center" LostFocus="PART_Edit_LostFocus" 
                 Text="{Binding Value, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Slider}, Mode=TwoWay}" />
    </ControlTemplate>

    <Style x:Uid="Style_3" x:Key="ThumbStyle" TargetType="{x:Type Thumb}">
        <Setter x:Uid="Setter_3" Property="Template" Value="{StaticResource StaticThumbTemplate}"/>
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsTyping, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Slider}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="True">
                <Setter x:Uid="Setter_4" Property="Template" Value="{StaticResource EditThumbTemplate}"/>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Slider.Resources>

<Slider.Template>
    <ControlTemplate x:Uid="ControlTemplate_5">
        <Grid x:Uid="Grid_1">
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Uid="ColumnDefinition_1" Width="*"/>
                <ColumnDefinition x:Uid="ColumnDefinition_2" Width="Auto"/>
                <ColumnDefinition x:Uid="ColumnDefinition_3" Width="Auto"/>
            </Grid.ColumnDefinitions>
            <Border x:Uid="Border_4" Grid.Column="0" BorderBrush="Gray" BorderThickness="1">
                <DockPanel x:Uid="PART_Outer" x:Name="PART_Outer" >
                    <Border x:Uid="Border_5" DockPanel.Dock="Left" Background="LightGray" Width="{Binding PadLeft, RelativeSource={RelativeSource Mode=TemplatedParent}}" Focusable="True"></Border>
                    <Border x:Uid="Border_6" DockPanel.Dock="Right" Background="LightGray" Width="{Binding PadRight, RelativeSource={RelativeSource Mode=TemplatedParent}}" Focusable="False"></Border>
                    <Track x:Uid="PART_Track" x:Name="PART_Track">
                        <Track.DecreaseRepeatButton>
                            <RepeatButton x:Uid="RepeatButton_1" Style="{StaticResource SliderLeftStyle}" Command="Slider.DecreaseLarge"/>
                        </Track.DecreaseRepeatButton>
                        <Track.Thumb>
                            <Thumb x:Uid="PART_Thumb" x:Name="PART_Thumb" Style="{StaticResource ThumbStyle}" MouseDoubleClick="PART_Thumb_OnMouseDoubleClick"/>
                        </Track.Thumb>
                        <Track.IncreaseRepeatButton>
                            <RepeatButton x:Uid="RepeatButton_2" Style="{StaticResource SliderRightStyle}" Command="Slider.IncreaseLarge" />
                        </Track.IncreaseRepeatButton>
                    </Track>
                </DockPanel>
            </Border>
            <RepeatButton x:Uid="RepeatButton_3" Grid.Column="1" Padding="4,0,4,0" Command="Slider.DecreaseSmall">&lt;</RepeatButton>
            <RepeatButton x:Uid="RepeatButton_4" Grid.Column="2" Padding="4,0,4,0" Command="Slider.IncreaseSmall">&gt;</RepeatButton>

        </Grid>

    </ControlTemplate>
</Slider.Template>

Slider.xaml.cs:

public partial class Slider 
{
    private bool _isTyping;
    public Slider()
    {
        InitializeComponent();
    }

    public bool IsTyping
    {
        get
        {
            return _isTyping;
        }
        set
        {
            _isTyping = value;
        }
    }

    private double _valStr;

    public double ValueStr
    {
        get { return _valStr; }
        set { _valStr = value; }
    }


    private void PART_Thumb_OnMouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
        IsTyping = true;
    }

    private void PART_Edit_LostFocus(object sender, RoutedEventArgs e)
    {
        IsTyping = false;
    }
}

【问题讨论】:

    标签: wpf xaml slider


    【解决方案1】:

    IsTyping 属性在哪里定义?如果它是Slider控件的DataContext的属性,则应添加“DataContext”。到绑定路径:

    <DataTrigger Binding="{Binding DataContext.IsTyping, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:Slider}}" Value="True">
    

    如果是在父窗口的视图模型中定义的,还应该更改AncestorType

    <DataTrigger Binding="{Binding DataContext.IsTyping, 
                  RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}" Value="True">
    

    还要确保IsTyping 是一个依赖属性,或者定义它的类实现了INotifyPropertyChanged 接口,并且当属性被设置为新值时,您会引发PropertyChanged 事件。

    【讨论】:

    • 我已经尝试使用给定的 sn-p 但没有运气,仍然无法正常工作:(。它既不是窗口也不是 UserControl。它是一个 [Slider] 控件 (Slider.xaml)。还有'IsTyping' 属性在 Slider.xaml.cs 中定义
    • 那么请把 Slider.xaml 的完整内容贴出来。
    • 添加了完整的代码。请检查一下。
    • IsTyping 应该是一个依赖属性或引发PropertyChanged 事件。
    • 太棒了!如果我将 IsTyping 设为 DependencyProperty,效果会很好。但不适用于 PropertyChanged 事件。如果可能的话,你能尽快解释一下吗?标记为“已接受的答案”。
    猜你喜欢
    • 2021-06-23
    • 1970-01-01
    • 2010-10-22
    • 2023-01-16
    • 2015-04-10
    • 2019-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多