我正在努力创建一个具有非常具体的 GUI 外观的应用程序。我的应用程序包含带有滚动条的 TreeView。不幸的是,滚动条非常基本,看起来就像典型的 Windows 滚动条。我需要它与我在应用程序中使用的 UI 纹理更紧密地匹配,但似乎无法弄清楚如何正确编辑 Thumb 以使其接受 .png。
.xaml 脚本
<Window x:Class="TestAPP.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestAPP"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<!-- Register ScrollThumbConverter -->
<local:ScrollThumbConverter x:Key="ScrollThumbConverter"/>
<local:ThumbHeightConverter x:Key="ThumbHeightConverter" />
<!-- Custom ScrollBar Style -->
<Style x:Key="CustomScrollBar" TargetType="{x:Type ScrollBar}">
<Setter Property="Width" Value="15"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid Background="Transparent" Margin="0,0,0,116">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Up Arrow -->
<RepeatButton Grid.Row="0" Height="15" Width="15"
Click="UpArrow_Click"
BorderThickness="0">
<RepeatButton.Background>
<ImageBrush ImageSource="/154965.png" Stretch="Fill"/>
</RepeatButton.Background>
</RepeatButton>
<!-- ScrollBar Track with MultiBinding -->
<Track Grid.Row="1" Name="PART_Track">
<Track.Thumb>
<Thumb Height="50" Width="15" BorderThickness="0" Padding="0">
<Thumb.Template>
<ControlTemplate TargetType="{x:Type Thumb}">
<Grid>
<Image Source="/154971.png" Stretch="Fill"/>
</Grid>
</ControlTemplate>
</Thumb.Template>
<!-- MultiBinding for thumb position -->
<Thumb.RenderTransform>
<MultiBinding Converter="{StaticResource ScrollThumbConverter}">
<Binding RelativeSource="{RelativeSource AncestorType=ScrollViewer}" Path="VerticalOffset" />
<Binding RelativeSource="{RelativeSource AncestorType=ScrollViewer}" Path="ScrollableHeight" />
<Binding RelativeSource="{RelativeSource AncestorType=ScrollViewer}" Path="ViewportHeight" />
</MultiBinding>
</Thumb.RenderTransform>
</Thumb>
</Track.Thumb>
</Track>
<!-- Down Arrow -->
<RepeatButton Grid.Row="2" Height="15" Width="15"
Click="DownArrow_Click"
BorderThickness="0">
<RepeatButton.Background>
<ImageBrush ImageSource="/154964.png" Stretch="Fill"/>
</RepeatButton.Background>
</RepeatButton>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<!-- ScrollViewer with custom scrollbar -->
<ScrollViewer x:Name="MyScrollViewer"
VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Disabled"
ScrollChanged="ScrollViewer_ScrollChanged">
<ScrollViewer.Style>
<Style TargetType="ScrollViewer">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ScrollContentPresenter Grid.Column="0"/>
<ScrollBar Grid.Column="1" Style="{StaticResource CustomScrollBar}" Orientation="Vertical"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ScrollViewer.Style>
<!-- Example content to scroll -->
<StackPanel>
<TextBlock Text="Line 1" Height="50"/>
<TextBlock Text="Line 2" Height="50"/>
<TextBlock Text="Line 3" Height="50"/>
<TextBlock Text="Line 4" Height="50"/>
<TextBlock Text="Line 5" Height="50"/>
<TextBlock Text="Line 6" Height="50"/>
<TextBlock Text="Line 7" Height="50"/>
<TextBlock Text="Line 8" Height="50"/>
<TextBlock Text="Line 9" Height="50"/>
<TextBlock Text="Line 10" Height="50"/>
</StackPanel>
</ScrollViewer>
</Grid>
</Window>
.xaml.cs 脚本
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
namespace TestAPP
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
// Scroll up when up arrow is clicked
private void UpArrow_Click(object sender, RoutedEventArgs e)
{
MyScrollViewer.LineUp(); // Scroll one line up
}
// Scroll down when down arrow is clicked
private void DownArrow_Click(object sender, RoutedEventArgs e)
{
MyScrollViewer.LineDown(); // Scroll one line down
}
// Handle scroll changes (you can manually adjust the thumb size or handle any visual logic here)
private void ScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e)
{
// Optional: Add any additional logic to manage thumb movement or other scroll events.
}
}
public class ScrollThumbConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length < 3 || !(values[0] is double verticalOffset) || !(values[1] is double scrollableHeight) || !(values[2] is double viewportHeight))
{
return new TranslateTransform(0, 0); // Default transform
}
// Calculate the thumb's position
double trackHeight = scrollableHeight + viewportHeight; // Total track height
double ratio = scrollableHeight > 0 ? verticalOffset / scrollableHeight : 0;
double thumbPosition = ratio * (trackHeight - viewportHeight); // Calculate thumb position
return new TranslateTransform(0, thumbPosition);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class ThumbHeightConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length < 2 || !(values[0] is double viewportHeight) || !(values[1] is double scrollableHeight))
{
return 50.0; // Default thumb height if values are missing
}
// Calculate the thumb height as a ratio of the viewport to the total scrollable height
double totalHeight = scrollableHeight + viewportHeight;
double thumbHeight = (viewportHeight / totalHeight) * viewportHeight;
return Math.Max(20, thumbHeight); // Ensure a minimum thumb height for usability
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
顺便说一句,我正在使用 .xaml (WPF) 和 C#。下面我添加了我正在使用的脚本的测试版本。箭头可以工作并且看起来与我想要的一模一样,但我无法让拇指正确显示。我做错了什么?
我尝试了您的代码,并且能够通过将解决方案资源管理器中的图像构建操作设置为“资源”来加载图像。 完成此操作后,您将需要运行
Build > Clean Solution
。 它将修改您的 csproj 以包含如下所示的项目:
<ItemGroup>
<None Remove="154965.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="154965.png" />
</ItemGroup>