如何编辑拇指以在 WPF 中使用自定义图像 (.png)?

问题描述 投票:0回答:1

我正在努力创建一个具有非常具体的 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#。下面我添加了我正在使用的脚本的测试版本。箭头可以工作并且看起来与我想要的一模一样,但我无法让拇指正确显示。我做错了什么?

c# wpf treeview
1个回答
0
投票

我尝试了您的代码,并且能够通过将解决方案资源管理器中的图像构建操作设置为“资源”来加载图像。 完成此操作后,您将需要运行

Build > Clean Solution
。 它将修改您的 csproj 以包含如下所示的项目:

  <ItemGroup>
    <None Remove="154965.png" />
  </ItemGroup>

  <ItemGroup>
    <Resource Include="154965.png" />
  </ItemGroup>
© www.soinside.com 2019 - 2024. All rights reserved.