1

Xaml ファイルの MahApps.Metro に付属する ModernUIIcons を StaticResources として使用しています。次のように、UI に配置するのは非常に簡単です。

<Rectangle  Width="19" 
            Height="19">
   <Rectangle.Fill>
      <VisualBrush Visual="{StaticResource appbar_database}" />
   </Rectangle.Fill>
</Rectangle>

四角形のすべてのロジックを CustomControl にカプセル化したいので、次のようなことができます。

<cc:MenuItemIcon Source="{StaticResource appbar_page}"/>

これは私がこれまでに得たものです:

ライブラリとしての 1 つのプロジェクトで、Themes/Generic.xaml:

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AMIGEDM.CustomControls.Menu">

<Style TargetType="{x:Type local:MenuItemIcon}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MenuItemIcon}">
                <Rectangle  Width="19" 
                            Height="19">
                    <Rectangle.Fill>
                        <VisualBrush Visual="{TemplateBinding Source}" />
                    </Rectangle.Fill>
                </Rectangle>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
</ResourceDictionary>

そしてCSファイルで

namespace AMIGEDM.CustomControls.Menu
{
   public class MenuItemIcon : Control
{
   static MenuItemIcon()
   {
      DefaultStyleKeyProperty.OverrideMetadata(typeof(MenuItemIcon), new  FrameworkPropertyMetadata(typeof(MenuItemIcon)));
   }

   public static readonly DependencyProperty SourceProperty =
      DependencyProperty.Register("Source", typeof(Visual), typeof(MenuItemIcon));

   public Visual Source
   {
      get { return (Visual)GetValue(SourceProperty); }
      set { SetValue(SourceProperty, value); }
   }
  }
}

すべてがスムーズにコンパイルされるので、TestDummy プロジェクトに移動します

<Window x:Class="AMIGEDM.TestDummy.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:cc="clr-namespace:AMIGEDM.CustomControls.Menu;assembly=AMIGEDM.CustomControls">
<Window.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="/AMIGEDM.TestDummy;component/Resources/Icons.xaml"/>
            <ResourceDictionary Source="pack://application:,,,/AMIGEDM.CustomControls;component/Themes/Generic.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Window.Resources>
<Grid>
    <Menu IsMainMenu="True" SnapsToDevicePixels="True">
        <MenuItem Header="_Open">
            <MenuItem Header="_File">
                <MenuItem.Icon>
                    <cc:MenuItemIcon Source="{StaticResource appbar_page}"/>
                </MenuItem.Icon>
            </MenuItem>
            <MenuItem Header="_File">
                <MenuItem.Icon>
                    <Rectangle  Width="19" 
                            Height="19">
                        <Rectangle.Fill>
                            <VisualBrush Visual="{StaticResource appbar_database}" />
                        </Rectangle.Fill>
                    </Rectangle>
                </MenuItem.Icon>
            </MenuItem>
        </MenuItem>
    </Menu>
</Grid>

ライブラリは、Rectangle、Rectangle Fill、および VisualBrush を使用してアイコンを配置しますが、CustomControl を使用しようとすると何も表示されません

ご覧のとおり、アイコンは完全な長方形を使用して表示されますが、カスタム コントロールでは表示されません。

4

1 に答える 1

1

のスタイルを除いて、すべてのコードは正常に見えますMenuItemIconTemplateBindingアダム・ネイサンの本からの引用:

TemplateBinding は、テンプレートの外部またはその VisualTree プロパティの外部では機能しないため、テンプレートのトリガー内で TemplateBinding を使用することさえできません。さらに、Freezable に適用された場合、TemplateBinding は機能しません (ほとんどの人為的な理由により)。

MSDNそして約から引用VisualBrush

Freezable 機能: VisualBrush クラスは Freezable クラスから継承されるため、いくつかの特別な機能を提供します。VisualBrush オブジェクトはリソースとして宣言し、複数のオブジェクト間で共有できます。

したがって、代わりに:

<VisualBrush Visual="{TemplateBinding Source}" />

値を取得する依存関係プロパティに等しい構造{RelativeSource TemplatedParent}を使用Pathします。

<Style TargetType="{x:Type local:MenuItemIcon}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:MenuItemIcon}">
                <Rectangle Width="22" Height="22">
                    <Rectangle.Fill>
                        <VisualBrush Visual="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Source}" />                                
                    </Rectangle.Fill>
                </Rectangle>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
于 2013-08-23T05:22:51.893 に答える