wpf - 在 Xaml 中,如何将滑块的 Thumb 绑定到多个 ControlTemplate 之一?
问题描述
我正在尝试在 WPF 中创建一个可编辑的滑块,我需要在其中将 ControlTemplate 与不起作用的 Slider thumb 的模板绑定。
我有 2 个 ControlTemplate 和一个滑块。滑块的拇指应根据控件模板的选择显示。
<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
从 true/false 更改,则应显示相应的 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"><</RepeatButton>
<RepeatButton x:Uid="RepeatButton_4" Grid.Column="2" Padding="4,0,4,0" Command="Slider.IncreaseSmall">></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;
}
}
解决方案
属性在哪里IsTyping
定义?如果是控件的属性DataContext
,Slider
则应添加“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
推荐阅读
- solr - 如何将 Solr Suggester ContextField 与布尔字段一起使用
- sql - 如何使用 PostgreSQL 选择语句引发错误?
- javascript - 将大数字字符串解析为数字格式
- java - yaml 配置文件中的全局参数配置
- c# - 从文本文件中替换可变长度的子字符串
- python - MoviePy 垂直文本问题
- database - 如何将谓词与通用存储库一起使用
- css - 如何在生产 React Rails(5.2.3) 中编译 css
- python-3.x - 面网格和点图没有给出准确的结果
- angular - 如何使用exceljs以角度导入EXCEL文件