Я создаю собственный TickBar для слайдера. Этот CustomTickBar позволяет мне ставить разные маркеры на слайдер. Я буду использовать следующую модель:
Interface IModel
{
string Id;
}
Class Model1 : IModel
{
string Id;
string SomeProperty;
}
Class Model2 : IModel
{
string Id;
string SomeOtherProperty;
}
Идея состоит в том, что я предоставляю List<IModel> этому элементу управления TickBar, и в зависимости от типа IModel значок маркера будет изменяться; например для Model1 это будет треугольник, а для Model2 - прямоугольник. Я понимаю, что это возможно с помощью DataTemplate. Но WPF TickBar не имеет свойства DataTemplate. Есть ли способ сделать это с помощью свойства DataTemplate и создания подкласса TickBar?
Примечание. Я понимаю, что могу создать собственный тик с помощью OnRender (), но я пытаюсь проверить, есть ли способ сделать это, написав как можно меньше кода программной части.
@ASh не могли бы вы привести пример? Не могу понять это.
@ASh Если бы вы читали исходный код TickBar, вы бы знали, что визуальный элемент TickBar был нарисован непосредственно в методе OnRender, потому что он зависит от других свойств динамически. Таким образом, DataTemplate решит вашу проблему, но замена OnRender поможет.
А как насчет положения клещей? вы хотите определить пользовательские позиции или как-то использовать частоту TickBar?
@Usama Я бы использовал нестандартные позиции. Таким образом, они могут появиться в любом месте ползунка.





Недавно я сам пробовал переопределить onrender для настраиваемого слайдера, и это сложно. Я бы не пошел по этому пути. Я предлагаю вам подумать о добавлении еще одного элемента управления, который будет удерживать маркеры и соответствовать высоте или ширине вашего слайдера. Если ваши «галочки» зафиксированы, то это может быть просто равномерная сетка, содержащая пути, и вы используете ресурс для определения их данных с помощью геометрии DynamicResource. Вы можете переключать геометрию, объединяя разные или наклеивая на нее данные.
TickBar не имеет стиля по умолчанию, поэтому похоже, что использование OnRender - это то, как они его разработали.
Другое решение, о котором я думаю, было бы:
TickBar, даже на основе некоторых данных вашей модели.Используйте themes/generic.xaml и этот код, чтобы применить собственный стиль для вашего элемента управления:
static void MyCustomTickBar() {
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyCustomTickBar), new FrameworkPropertyMetadata(typeof(MyCustomTickBar)));
}
Slider и используйте новый TickBar вместо встроенного.Здесь - шаблон по умолчанию для слайдера. Я использовал style snooper, чтобы извлечь его. Извините, я не смог указать это в своем ответе, это слишком долго.
Попробуйте сначала создать стиль для слайдера. например Что-то вроде этого:
<Window.Resources>
<SolidColorBrush x:Key = "HorizontalSliderTrackNormalBackground" Color = "#FFE7EAEA"/>
<LinearGradientBrush x:Key = "HorizontalSliderTrackNormalBorder" EndPoint = "0,1" StartPoint = "0,0">
<GradientStop Color = "#FFAEB1AF" Offset = "0.1"/>
<GradientStop Color = "#FFAEB1AF" Offset = ".9"/>
</LinearGradientBrush>
<Style x:Key = "SliderRepeatButtonStyle" TargetType = "{x:Type RepeatButton}">
<Setter Property = "OverridesDefaultStyle" Value = "true"/>
<Setter Property = "IsTabStop" Value = "false"/>
<Setter Property = "Focusable" Value = "false"/>
<Setter Property = "Template">
<Setter.Value>
<ControlTemplate TargetType = "{x:Type RepeatButton}">
<Rectangle Fill = "Transparent"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key = "CustomThumbForSlider" TargetType = "{x:Type Thumb}">
<Setter Property = "OverridesDefaultStyle" Value = "True"/>
<Setter Property = "Template">
<Setter.Value>
<ControlTemplate TargetType = "{x:Type Thumb}">
<Ellipse Fill = "#009EFF" Stroke = "#009EFF" Height = "14" Width = "14"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key = "MyCustomStyleForSlider" TargetType = "{x:Type Slider}">
<Setter Property = "Template">
<Setter.Value>
<ControlTemplate TargetType = "{x:Type Slider}">
<Border Background = "{TemplateBinding Background}" BorderBrush = "{TemplateBinding BorderBrush}" BorderThickness = "{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height = "auto"/>
<RowDefinition Height = "Auto" MinHeight = "{TemplateBinding MinHeight}"/>
<RowDefinition Height = "Auto"/>
</Grid.RowDefinitions>
<TickBar x:Name = "TopTick" Visibility = "Collapsed" Fill = "{TemplateBinding Foreground}" Placement = "Top" Height = "10" Grid.Row = "2"/>
<TickBar x:Name = "BottomTick" Visibility = "Collapsed" Fill = "{TemplateBinding Foreground}" Placement = "Bottom" Height = "10" Grid.Row = "2"/>
<Border x:Name = "TrackBackground"
Background = "{StaticResource HorizontalSliderTrackNormalBackground}"
BorderBrush = "{StaticResource HorizontalSliderTrackNormalBorder}"
BorderThickness = "2" CornerRadius = "1"
Margin = "5,0" VerticalAlignment = "Center" Height = "10.0" Grid.Row = "1" >
<Canvas Margin = "-6,-2">
<Rectangle Visibility = "Hidden" x:Name = "PART_SelectionRange" Height = "6.0"
Fill = "{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"
Stroke = "{DynamicResource {x:Static SystemColors.ControlDarkDarkBrushKey}}"
StrokeThickness = "2.0"/>
</Canvas>
</Border>
<Track x:Name = "PART_Track" Grid.Row = "1" >
<Track.DecreaseRepeatButton>
<RepeatButton Style = "{StaticResource SliderRepeatButtonStyle}" Command = "{x:Static Slider.DecreaseLarge}"/>
</Track.DecreaseRepeatButton>
<Track.IncreaseRepeatButton>
<RepeatButton Style = "{StaticResource SliderRepeatButtonStyle}" Command = "{x:Static Slider.IncreaseLarge}"/>
</Track.IncreaseRepeatButton>
<Track.Thumb>
<Thumb x:Name = "Thumb" Style = "{StaticResource CustomThumbForSlider}" Background = "Black"/>
</Track.Thumb>
</Track>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
Затем вы можете определить слайдер, который использует стиль:
<Slider Name = "CustomSlider" Style = "{StaticResource MyCustomStyleForSlider}"/>
Чтобы изменить стиль в зависимости от некоторых свойств, вы можете добавить триггер данных. просто замените существующий стиль новым:
<Style x:Key = "CustomThumbForSlider" TargetType = "{x:Type Thumb}">
<Setter Property = "OverridesDefaultStyle" Value = "True"/>
<Setter Property = "Template">
<Setter.Value>
<ControlTemplate TargetType = "{x:Type Thumb}">
<Ellipse Fill = "#009EFF" Stroke = "#009EFF" Height = "14" Width = "14"/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding = "{Binding Path=IsDifferent}" Value = "True">
<Setter Property = "Template">
<Setter.Value>
<ControlTemplate TargetType = "{x:Type Thumb}">
<Ellipse Fill = "#009055" Stroke = "#009055" Height = "14" Width = "14"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
Этот новый стиль изменит внешний вид, когда контекст данных слайдера имеет другое значение для свойства IsDifferent.
<Slider Name = "CustomSlider" Style = "{StaticResource MyCustomStyleForSlider}" DataContext = "{Binding Path=MyContext}"/>
Конечно, можно было бы заменить зеленый эллипс другой формой по своему вкусу, а также использовать другое свойство.
Для задачи создания шаблонов обычно лучше использовать ControlTemplate или, альтернативно, ContentControl, DataTemplate которого может быть установлен свободно и который будет выступать в качестве родительского элемента для ваших собственных элементов управления.
CustomTickBar может иметь настраиваемые маркеры, которые, в свою очередь, могут иметь свойство DataTemplate.