2013-08-30 54 views
9

すべてCheckBoxの代わりに画像を使用するCheckBoxというカスタムを作成しました。これはうまくいくが、私は必要に応じて画像を変更できるようにしたい。理想的には、アプリケーションリソースProperties.Resources.SomeImage16(.pngファイル)を使用したいと考えています。 XAMLは、実装にWPFのカスタムチェックボックスで画像を変更

<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のために使用された画像に変更するにはどうすればよい(すなわちを変更する固定/非固定/ダニなど横断する)することなく、新しいスタイル/テンプレートを作成しますか?

お時間をいただきありがとうございます。

+4

1 - すべてのPNGを使用しないでください。 WPFはwinformsではありません。可能であれば、ベクターグラフィックを使用してください。 2 - いくつかの 'Attached Properties'を作成し、' ControlTemplate'にバインドすることができます。 –

+0

これが許可されていれば、.NETアプリケーションはどのドライブにもアクセスできます。 – Paparazzi

+0

あなたが何を求めているのかはっきりしません...チェックボックスの状態に基づいてイメージを変更することはどうですか?そうであれば、トリガーを使用することはできますが、既にいくつかのトリガーがあります。試したソリューションは機能していないので、動作させるには手助けが必要ですか? –

答えて

12

が既にベクタグラフィックスを使用する機能のための@HighCore必要性を述べたように。この場合、Pathを使用するには、Dataのどこにオブジェクトが描画される指定座標(MSDN)を使用しますか。

利点:

  • は小さいサイズ

  • が動的に(私の意見では)色、大きさ、全体形状

マイナスの変更、ファイルに保管しないでください。 :

  • あなたはいつもPath

についてマイナスのために右のDataを見つけることができません。Dataに画像を変換するための特別サイト(www.modernuiicons.com)とユーティリティがあります。

変更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

enter image description here

我々はまた、資源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

、私は2つの添付依存関係プロパティ(文字列型を作成しました):

  • IsCheckedOnData

  • IsCheckedOffData

IsCheckedOnDataIsChecked = "False"によってIsChecked = "True"によってData値、IsCheckedOffData値が含まれています。

これで、アイコンの文字列を特定し、そのようなリソースを定義するだけで済みます(たとえば)。

全例:TemplateBindingは、テンプレートの外またはそのVisualTreeプロパティ外では動作しませんので、私はTemplateBindingを使用していないスタイルで

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をテンプレートの中に使うことさえできません食べたのトリガー。したがって、値を取得したい依存性プロパティと同等の構造{RelativeSource TemplatedParent}Pathを使用する必要があります。

+0

返信いただきありがとうございます。このような広範囲の文字列を画像データに使用することは奇妙に思えます。これが本当に標準的な方法であれば、そうしてください。私は自分のアイコンを表現デザインでデザインしていますので、変換ユーティリティを調べます...カスタムチェックボックスの実際のイメージを変更する方法を知りたかったので、ダニと十字を表示したい代わりに、別のスタイルを作成することでこれをどのように行うことができますか?これは不可能ですか? – MoonKnight

+1

@Killercam:私の編集をご覧ください。 –

+1

本当にこれを感謝します。ありがとう、良い週末を持っています... – MoonKnight

1

申し訳ありませんが、私はそれらのリソースでイメージを参照する方法はまだ分かりませんが、イメージをアプリケーションルートディレクトリのImagesという名前のフォルダに追加することができれば、この:

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

返信ありがとう... – MoonKnight

関連する問題