簡體   English   中英

在 WPF 中更改自定義復選框上的圖像

[英]Change Images on Custom CheckBox in WPF

我創建了以下自定義CheckBox ,它使用圖像而不是CheckBox 但是,這很有效,我希望能夠根據需要更改圖像。 理想情況下,我想使用應用程序資源Properties.Resources.SomeImage16 (一個 .png 文件)。 XAML 是

<Style x:Key="styleCustomCheckBox" 
       TargetType="{x:Type CheckBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <StackPanel Orientation="Horizontal">
                    <Image x:Name="imageCheckBox" 
                           Width="16" 
                           Height="16" 
                           Source="F:\Camus\ResourceStudio\Graphics\Images\UnPinned16.png"/>
                    <ContentPresenter VerticalAlignment="Center"/>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="False">
                        <Setter TargetName="imageCheckBox" 
                                Property="Source" 
                                Value="F:\Camus\ResourceStudio\Graphics\Images\Pinned16.png"/>
                    </Trigger>
                    <Trigger Property="IsChecked" Value="True">
                        <Setter TargetName="imageCheckBox" 
                                Property="Source"
                                Value="F:\Camus\ResourceStudio\Graphics\Images\UnPinned16.png"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

隨着實施

<ListBox SelectionMode="Single" >
    <StackPanel Orientation="Horizontal">
        <CheckBox Style="{StaticResource styleCustomCheckBox}" 
                  HorizontalAlignment="Left" 
                  VerticalAlignment="Center"
                  Margin="4,0,4,0"/>
        <TextBlock VerticalAlignment="Top" 
                   Text="SomeRecentDocument.resx"/>
    </StackPanel>
</ListBox>

如何更改用於自定義CheckBox的圖像(即,將固定/未固定到勾號/十字等)而不必創建新樣式/模板?

謝謝你的時間。

正如已經提到的@HighCore需要能夠使用矢量圖形。 在這種情況下,要使用Path ,其中Data到繪制對象的指定坐標 ( MSDN )。

優點:

  • 不要將它存儲在文件中,較小的尺寸

  • 動態改變顏色、大小和整體形狀

缺點(在我看來):

  • 您無法始終為Path找到正確的Data

關於減號:有一些特殊的站點 ( www.modernuiicons.com ) 和用於將圖像轉換為Data實用程序。

使用Path更改CheckBox的樣式:

Style

<Style x:Key="styleCustomCheckBox" TargetType="{x:Type CheckBox}">
        <Setter Property="FontFamily" Value="Verdana" />
        <Setter Property="FontSize" Value="14" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}">
                    <StackPanel Orientation="Horizontal">
                        <Path x:Name="MyPin" Width="18" Height="18" Stretch="Fill" Fill="#FF000000"
                              Data="F1 M 56.1355,32.5475L 43.4466,19.8526C 42.7886,20.4988 42.298,21.2123 41.9749,21.9932C 41.6519,22.7741 41.4903,23.5729 41.4903,24.3895C 41.4903,25.1942 41.6529,25.987 41.9779,26.7679L 34.0577,34.6821C 33.3918,34.3372 32.6991,34.0776 31.9796,33.9032C 31.2601,33.7288 30.5298,33.6415 29.7885,33.6415C 28.623,33.6415 27.4953,33.8526 26.4052,34.2748C 25.315,34.697 24.3419,35.3342 23.4856,36.1865L 30.2344,42.9174L 25.9027,47.9032L 22.6532,51.8425L 20.5988,54.5836C 20.1212,55.2892 19.8823,55.753 19.8823,55.975L 19.8645,56.0701L 19.9002,56.088L 19.9002,56.1474L 19.9358,56.1058L 20.0131,56.1236C 20.2351,56.1236 20.6989,55.8888 21.4045,55.419L 24.1457,53.3765L 28.0849,50.1151L 33.0945,45.7775L 39.8016,52.5025C 40.6579,51.6462 41.2961,50.6731 41.7163,49.5829C 42.1365,48.4928 42.3466,47.367 42.3466,46.2056C 42.3466,45.4603 42.2603,44.729 42.0879,44.0115C 41.9155,43.294 41.6548,42.6003 41.3069,41.9304L 49.2202,34.0161C 50.0011,34.3372 50.7939,34.4978 51.5986,34.4978C 52.4192,34.4978 53.2189,34.3362 53.9979,34.0132C 54.7768,33.6901 55.4894,33.2015 56.1355,32.5475 Z "/>

                        <ContentPresenter VerticalAlignment="Center" Margin="10,0,0,0" />
                    </StackPanel>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="False">
                            <Setter TargetName="MyPin" Property="Data" Value="F1 M 32.3691,30.2225L 33.2253,29.3901L 15.361,11.5258C 13.9814,12.7067 12.6951,13.9936 11.5148,15.3738L 26.6252,30.4842C 27.743,30.1631 28.8767,30.0025 30.0263,30.0025C 30.8191,30.0025 31.6,30.0759 32.3691,30.2225 Z M 45.5039,49.3629L 60.6292,64.4826C 62.0123,63.2996 63.3017,62.0101 64.4846,60.6268L 46.6218,42.7866L 45.7834,43.619L 45.9439,44.7726L 45.9915,45.9261L 45.8785,47.6713L 45.5039,49.3629 Z M 56.1355,32.5475L 43.4466,19.8526C 42.7886,20.4987 42.298,21.2123 41.9749,21.9932C 41.6519,22.7741 41.4903,23.5729 41.4903,24.3895C 41.4903,25.1942 41.6529,25.987 41.9779,26.7679L 34.0577,34.6821C 33.3918,34.3372 32.6991,34.0776 31.9796,33.9032C 31.2601,33.7288 30.5298,33.6415 29.7885,33.6415C 28.623,33.6415 27.4953,33.8526 26.4052,34.2748C 25.315,34.697 24.3419,35.3342 23.4856,36.1865L 30.2344,42.9174L 25.9027,47.9032L 22.6532,51.8425L 20.5988,54.5836C 20.1212,55.2892 19.8823,55.753 19.8823,55.975L 19.8645,56.0701L 19.9002,56.0879L 19.9002,56.1474L 19.9358,56.1058L 20.0131,56.1236C 20.2351,56.1236 20.6989,55.8888 21.4045,55.419L 24.1457,53.3765L 28.0849,50.1151L 33.0945,45.7775L 39.8016,52.5025C 40.6579,51.6462 41.2961,50.6731 41.7163,49.5829C 42.1365,48.4928 42.3466,47.367 42.3466,46.2056C 42.3466,45.4603 42.2603,44.729 42.0879,44.0115C 41.9155,43.294 41.6548,42.6003 41.306,41.9304L 49.2202,34.0161C 50.0011,34.3372 50.7939,34.4978 51.5986,34.4978C 52.4192,34.4978 53.219,34.3362 53.9979,34.0132C 54.7768,33.6901 55.4894,33.2015 56.1355,32.5475 Z " />                                
                            <Setter TargetName="MyPin" Property="Fill" Value="Gray" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
</Style>

Using

<StackPanel Orientation="Vertical" HorizontalAlignment="Center">
    <CheckBox Height="35"
              Style="{StaticResource styleCustomCheckBox}" 
              Content="MySolution1" />

    <CheckBox Height="35"
              Style="{StaticResource styleCustomCheckBox}" 
              Content="MySolution2" />
</StackPanel>

Output

在此處輸入圖片說明

我們還可以將Path's存儲在資源中,並像這樣引用它們:

<Path x:Key="MyPath" Data="F1 M 38,19C 48.4934,19 57,27.5066 ... />

...

<Setter TargetName="MainPath" Property="Data"
        Value="{Binding Source={StaticResource MyPath}, Path=Data}" />

Edit

為了指定任意圖標,我創建了兩個附加的依賴屬性(字符串類型):

  • 已檢查數據

  • IsCheckedOffData

IsCheckedOnData包含IsChecked = "True" Data值, IsChecked = "False" IsCheckedOffData值。

現在您只需要確定圖標字符串並定義這樣的資源(例如)。

完整示例:

XAML

<Window x:Class="CustomCheckBoxHelp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:CustomCheckBoxHelp"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    WindowStartupLocation="CenterScreen"
    Title="MainWindow" Height="350" Width="525">

<Window.Resources>
    <sys:String x:Key="Up">
        F1 M 37.8516,35.625L 34.6849,38.7917L 23.6016,50.2708L 
        23.6016,39.9792L 37.8516,24.9375L 52.1016,39.9792L 52.1016,
        50.2708L 41.0182,38.7917L 37.8516,35.625 Z
    </sys:String>

    <sys:String x:Key="Down">
        F1 M 37.8516,39.5833L 52.1016,24.9375L 52.1016,35.2292L 
        37.8516,50.2708L 23.6016,35.2292L 23.6016,24.9375L 37.8516,39.5833 Z
    </sys:String>

    <Style x:Key="styleCustomCheckBox" TargetType="{x:Type CheckBox}">
        <Setter Property="FontFamily" Value="Verdana" />
        <Setter Property="FontSize" Value="14" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type CheckBox}">
                    <StackPanel Orientation="Horizontal">
                        <Path x:Name="MyPin" Width="18" Height="18" Stretch="Fill" Fill="#FF000000" 
                              Data="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:CustomCheckBoxClass.IsCheckedOnData)}" />
                        <ContentPresenter VerticalAlignment="Center" Margin="10,0,0,0" />
                    </StackPanel>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsChecked" Value="False">
                            <Setter TargetName="MyPin" Property="Data"
                                    Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(local:CustomCheckBoxClass.IsCheckedOffData)}" />
                            <Setter TargetName="MyPin" Property="Fill" Value="Gray" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</Window.Resources>

<Grid>
    <StackPanel Orientation="Vertical" HorizontalAlignment="Center" Background="Beige">
        <CheckBox Height="35" 
                  local:CustomCheckBoxClass.IsCheckedOnData="{StaticResource Up}"
                  local:CustomCheckBoxClass.IsCheckedOffData="{StaticResource Down}"
                  Style="{StaticResource styleCustomCheckBox}" 
                  Content="MySolution1" />

        <CheckBox Height="35" 
                  local:CustomCheckBoxClass.IsCheckedOnData="{StaticResource Up}"
                  local:CustomCheckBoxClass.IsCheckedOffData="{StaticResource Down}"
                  Style="{StaticResource styleCustomCheckBox}" 
                  Content="MySolution2" />
    </StackPanel>
</Grid>
</Window>

Code behind

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();            
    }
}

public class CustomCheckBoxClass : DependencyObject
{
    #region IsCheckedOnDataProperty

    public static readonly DependencyProperty IsCheckedOnDataProperty;

    public static void SetIsCheckedOnData(DependencyObject DepObject, string value)
    {
        DepObject.SetValue(IsCheckedOnDataProperty, value);
    }

    public static string GetIsCheckedOnData(DependencyObject DepObject)
    {
        return (string)DepObject.GetValue(IsCheckedOnDataProperty);
    }

    #endregion

    #region IsCheckedOffDataProperty

    public static readonly DependencyProperty IsCheckedOffDataProperty;

    public static void SetIsCheckedOffData(DependencyObject DepObject, string value)
    {
        DepObject.SetValue(IsCheckedOffDataProperty, value);
    }

    public static string GetIsCheckedOffData(DependencyObject DepObject)
    {
        return (string)DepObject.GetValue(IsCheckedOffDataProperty);
    }

    #endregion

    static CustomCheckBoxClass()
    {
        PropertyMetadata MyPropertyMetadata = new PropertyMetadata(string.Empty);

        IsCheckedOnDataProperty = DependencyProperty.RegisterAttached("IsCheckedOnData",
                                                            typeof(string),
                                                            typeof(CustomCheckBoxClass),
                                                            MyPropertyMetadata);

        IsCheckedOffDataProperty = DependencyProperty.RegisterAttached("IsCheckedOffData",
                                                            typeof(string),
                                                            typeof(CustomCheckBoxClass),
                                                            MyPropertyMetadata);
    }        
}

Note:在樣式中,我沒有使用TemplateBinding因為TemplateBinding在模板之外或其 VisualTree 屬性之外不起作用,所以你甚至不能在模板的觸發器內使用TemplateBinding 因此,我們必須使用構造{RelativeSource TemplatedParent}和等於要檢索其值的依賴屬性的Path

抱歉,我還不知道如何在這些資源中引用圖像,但是如果您可以將圖像添加到應用程序根目錄中名為Images的文件夾中,那么您將能夠像這樣簡單地引用圖像:

<Image Source="/ApplicationName;component/Images/SomeImage16.png" />

正如您提到的,您可以通過選中和取消選中來更改復選框觸發器。 並且圖像會顯示相應的觸發器。 您的 xml 代碼對我很有用。我只是刪除了觸發器 true 部分。因為默認情況下 false 部分在焦點上,單擊復選框圖像 UnPinned16.png 后可見。 並且 agan 單擊圖像 Pinned16.png 是 visibale 。

<Style x:Key="styleCustomCheckBox" 
       TargetType="{x:Type CheckBox}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type CheckBox}">
                <StackPanel Orientation="Horizontal">
                    <Image x:Name="imageCheckBox" 
                           Width="16" 
                           Height="16" Source="F:\Camus\ResourceStudio\Graphics\Images\UnPinned16.png"/>
                    <ContentPresenter VerticalAlignment="Center"/>
                </StackPanel>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsChecked" Value="False">
                        <Setter TargetName="imageCheckBox" 
                                Property="Source" 
                                Value="F:\Camus\ResourceStudio\Graphics\Images\Pinned16.png"/>
                    </Trigger>                        
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我在文本塊下使用此復選框

<CheckBox Style="{StaticResource styleCustomCheckBox}" 
                  HorizontalAlignment="Left" 
                  VerticalAlignment="Center"
                  Margin="4,0,4,0"/>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM