如何在WPF中动态更改滚动条背景图片?

时间:2018-12-31 16:48:31

标签: c# wpf data-binding

这个问题很难以清楚的方式提出。但是,我会尽力而为...

标题中的“滚动条背景”是指如下图所示的轨道区域(从https://www.codeproject.com/Articles/41787/Creating-a-Blend-like-Scrollbar明显被盗)。

Parts of a scrollbar

显然,stackoverflow不允许我嵌入图像。因此,我希望上面的链接有效。

此外,标题中的“动态”一词并不意味着将一个资源映像换成另一个。这意味着在内存中创建图像,然后在运行时将其分配给滚动条。

我整理了一个简单的项目来演示我正在尝试做的事情。这是屏幕截图。

Screenshot of desired effect

等等!停止。请不要建议我“处理”到Winmerge之类的第三方应用程序。请记住,这只是一个演示应用程序,可帮助您传达想法。我的真实应用程序没有比较文本文件,尽管最终结果将非常相似。

这是我的演示应用程序的XAML的一部分。

<Grid>
    <DataGrid Name="dgDiffs" AutoGenerateColumns="False">
        <DataGrid.Resources>
            <Style TargetType="ScrollBar">
                <Setter Property="Background">
                    <Setter.Value>
                        <!--<ImageBrush ImageSource="{Binding overview}" />-->
                        <ImageBrush ImageSource="overview.png" />
                    </Setter.Value>

如您所见,我已经为演示(overview.png)进行了硬编码。您还可以看到我试图将图像源绑定到C#中的对象的位置。我的想法是我以编程方式创建一个显示概述的位图,然后更新滚动条。

这就是我被困住的地方。我尝试创建简单的位图对象并用纯色填充它们,但是它们没有出现在我的滚动条上。我什至不确定我是否会采用正确的方法。

这是我的演示代码,试图使用位图对象。

public partial class MainWindow : Window {

    class DiffItem {
        public int diff { get; set; } // used to color grid row (highlight differences)
        public string leftString { get; set; }
        public string rightString { get; set; }
    }

    public MainWindow() {
        InitializeComponent();

        // build a lengthy list for demonstration
        List<DiffItem> diffList = new List<DiffItem>();
        for (int i = 0; i < 10; i++) {
            // I've chopped out a bunch of lines here. This just builds a long repeating list for the demo
            diffList.Add(new DiffItem() { diff = 0, leftString = "one", rightString = "one" });
            diffList.Add(new DiffItem() { diff = -1, leftString = "four", rightString = "" });
            diffList.Add(new DiffItem() { diff = 1, leftString = "", rightString = "eight" });
            diffList.Add(new DiffItem() { diff = 2, leftString = "eleven", rightString = "elven" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "sixteen", rightString = "sixteen" });
        }

        // display list
        dgDiffs.ItemsSource = diffList;

        // update scrollbar overview
        Bitmap overview = new Bitmap(20, 200);
        using (Graphics g = Graphics.FromImage(overview)) {
            g.Clear(Color.Green);
        }
    }
}

这是XAML试图绑定滚动条的图像源。

<Grid>
    <DataGrid Name="dgDiffs" AutoGenerateColumns="False">
        <DataGrid.Resources>
            <Style TargetType="DataGridRow">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding diff}" Value="2">
                        <Setter Property="Background" Value="Orange" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding diff}" Value="1">
                        <Setter Property="Background" Value="LightGreen" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding diff}" Value="-1">
                        <Setter Property="Background" Value="OrangeRed" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
            <Style TargetType="ScrollBar">
                <Setter Property="Background">
                    <Setter.Value>
                        <ImageBrush ImageSource="{Binding overview}" />
                        <!--<ImageBrush ImageSource="overview.png" />-->
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding leftString}" Width="200"></DataGridTextColumn>
            <DataGridTextColumn Binding="{Binding rightString}" Width="*"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

1 个答案:

答案 0 :(得分:0)

万一有人想知道...这是怎么做。

XAML

<Grid>
    <DataGrid Name="dgDiffs" AutoGenerateColumns="False">
        <DataGrid.Resources>
            <Style TargetType="DataGridRow">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding diff}" Value="2">
                        <Setter Property="Background" Value="Orange" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding diff}" Value="1">
                        <Setter Property="Background" Value="LightGreen" />
                    </DataTrigger>
                    <DataTrigger Binding="{Binding diff}" Value="-1">
                        <Setter Property="Background" Value="OrangeRed" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
            <Style TargetType="ScrollBar">
                <Setter Property="Background">
                    <Setter.Value>
                        <ImageBrush ImageSource="{Binding Path=overview}" />
                        <!--<ImageBrush ImageSource="overview.png" />-->
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding leftString}" Width="200"></DataGridTextColumn>
            <DataGridTextColumn Binding="{Binding rightString}" Width="*"></DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

C#

public partial class MainWindow : Window {

    class DiffItem {
        public int diff { get; set; } // used to color grid row (highlight differences)
        public string leftString { get; set; }
        public string rightString { get; set; }
    }

    public BitmapImage overview { get; set; }

    public MainWindow() {
        InitializeComponent();
        DataContext = this;

        // build a lengthy list for demonstration
        List<DiffItem> diffList = new List<DiffItem>();
        for (int i = 0; i < 10; i++) {
            diffList.Add(new DiffItem() { diff = 0, leftString = "one", rightString = "one" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "two", rightString = "two" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "three", rightString = "three" });
            diffList.Add(new DiffItem() { diff = -1, leftString = "four", rightString = "" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "five", rightString = "five" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "six", rightString = "six" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "seven", rightString = "seven" });
            diffList.Add(new DiffItem() { diff = 1, leftString = "", rightString = "eight" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "nine", rightString = "nine" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "ten", rightString = "ten" });
            diffList.Add(new DiffItem() { diff = 2, leftString = "eleven", rightString = "elven" });
            diffList.Add(new DiffItem() { diff = 2, leftString = "twelv", rightString = "twelve" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "thirteen", rightString = "thirteen" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "fourteen", rightString = "fourteen" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "fifteen", rightString = "fifteen" });
            diffList.Add(new DiffItem() { diff = 0, leftString = "sixteen", rightString = "sixteen" });
        }

        // display list
        dgDiffs.ItemsSource = diffList;

        // create the overview bitmap
        Bitmap bmp = new Bitmap(20, 200, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
        using (Graphics g = Graphics.FromImage(bmp)) {
            Pen greenPen = new Pen(Color.Green, 1);
            g.Clear(Color.White);
            g.DrawLine(greenPen, 0, 50, 20, 50);
        }
        MemoryStream memoryStream = new MemoryStream();
        bmp.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);

        // load scrollbar with overview
        overview = new BitmapImage();
        overview.BeginInit();
        overview.StreamSource = memoryStream;
        overview.EndInit();
        overview.Freeze();
    }
}