0

アプリ全体にアイコンとテキストを含むボタンが大量にあり、それらすべてに共通のスタイルを抽出しようとしています。私は、ボタンから派生するというこのアイデアを思いつき、いくつかの依存関係プロパティを持っています。このカスタム ボタン クラスには、アプリケーション内のすべてのボタンに共通のスタイルがあります。

私のカスタムボタンの定義:

<Button x:Class="UIElements.Controls.CustomToolBarButton"
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
               xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
               xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" mc:Ignorable="d"
               >
<!--Style="{StaticResource ResourceKey=ToolBarButtonStyle}"-->
<StackPanel Orientation="Horizontal">
    <Image Source="{Binding Icon, Mode=TwoWay}" Style="{StaticResource ResourceKey=ToolBarButtonIconStyle}" />
    <TextBlock Text="{Binding DisplayText, Mode=TwoWay}" Style="{StaticResource ResourceKey=ToolBarButtonDisplayTextStyle}" />
</StackPanel>

using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
//using Telerik.Windows.Controls;

namespace UIElements.Controls
{
    public partial class CustomToolBarButton : Button
    {
        public CustomToolBarButton()
        {
            InitializeComponent();
            this.DataContext = this;
        }

        public static readonly DependencyProperty IconProperty =
            DependencyProperty.Register("Icon", typeof(BitmapImage), typeof(Button), new PropertyMetadata(default(BitmapImage)));

        public BitmapImage Icon
        {
            get { return (BitmapImage)GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }

        public static readonly DependencyProperty DisplayTextProperty =
            DependencyProperty.Register("DisplayText", typeof(string), typeof(Button), new PropertyMetadata(default(string)));

        public string DisplayText
        {
            get { return (string) GetValue(DisplayTextProperty); }
            set { SetValue(DisplayTextProperty, value); }
        }
    }
}

そして、私はこのコントロールを次のように使用しています:

<Controls1:CustomToolBarButton Icon="{DynamicResource ImageSave}"
                        DisplayText="Test Display">
<Controls1:CustomToolBarButton.Style>
    <Style TargetType="Controls1:CustomToolBarButton">
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding SelectedListItem.ListId}" Value="0" />
                </MultiDataTrigger.Conditions>
                <!--<Setter Property="Button.IsEnabled" Value="False" />-->
                <Setter Property="Background" Value="BurlyWood" />
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</Controls1:CustomToolBarButton.Style>

うまくいっているように見えますが、制限されたデータが変更されたときにトリガーが起動しません。同じトリガーを通常のボタンに適用すると、うまく機能しているようです。

何か不足している場合は教えてください。

編集:エレガントなソリューション が見つかりました。添付プロパティの利用

4

3 に答える 3

0

このコード行を静的コンストラクターに追加します

DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomToolBarButton), new FrameworkPropertyMetadata(typeof(CustomToolBarButton)));

http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.defaultstylekey.aspx

于 2012-11-20T02:11:28.803 に答える
0

まず第一に、絶対に使用しないthis.DataContext = this;でください。

次に、ボタンから継承する場合は、XAML ファイルを作成するのではなく、Themes/Generic.xamlリソース ディクショナリに既定のスタイルを作成する必要があります (UserControlこのようなファイルから継承する場合は問題ありません)。

Control.Templateこれは、スタイルでa を定義する必要があることも意味するためTemplateBindings、通常のものの代わりに を使用する (または を使用するRelativeSource) 必要があります。

別の回答で述べたように、メタデータをオーバーライドする必要がある場合があります。

于 2012-11-21T01:08:54.430 に答える
0

では、それをボタン自体にCustomToolBarButton設定しています( )。これを行うことで、(プロパティを含む) ボタンへの親 (ボタンの親コントロール、グリッドまたは UserControl など) のデータ コンテキストの伝播を停止しました。DataContextthis.DataContext = this;SelectedListItem

これを修正したいだけの場合は、RelativeSourceまたはBinding を使用してボタンの親コントロールにアクセスElementNameし、それを使用して.DataContextSelectedListItem

<Grid x:Name="ParentGrid">

    <Controls1:CustomToolBarButton Icon="{DynamicResource ImageSave}"
                            DisplayText="Test Display">
    <Controls1:CustomToolBarButton.Style>
        <Style TargetType="Controls1:CustomToolBarButton">
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding ElementName=ParentGrid,
                           Path=DataContext.SelectedListItem.ListId}" Value="0" />
                    </MultiDataTrigger.Conditions>
                    <!--<Setter Property="Button.IsEnabled" Value="False" />-->
                    <Setter Property="Background" Value="BurlyWood" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </Controls1:CustomToolBarButton.Style>
</Grid>

ボタンを拡張するために UserControl を使用したため、問題が発生しています。あなたが言ったように、ボタンがたくさんあるので、このCustomControlような with テンプレートを作成することをお勧めします; そうすれば、DataContext の伝播をいじる必要がなくなります。

これは、あなたが望むことを正確に行うためのさまざまな方法を説明するブログです -

http://blogs.msdn.com/b/knom/archive/2007/10/31/wpf-control-development-3-ways-to-build-an-imagebutton.aspx

于 2012-11-20T11:00:57.190 に答える