簡體   English   中英

無法獲取/設置自定義附加屬性

[英]Failing to get/set custom attached property

我正在嘗試創建一個帶有圖標的“ DropDownButton”,並且希望能夠通過附加屬性設置圖標源(我發現這是(唯一的)方法)。 但是由於某種原因,我嘗試的所有操作都失敗了,我能得到的最好的是一個空的Image容器。

我以為這看起來不錯,但是現在出現了以下錯誤:

The local property "Image" can only be applied to types that are derived from "IconButton".
The attachable property 'Image' was not found in type 'IconButton'.
The attached property 'IconButton.Image' is not defined on 'Button' or one of its base classes.

我可能完全錯了(我已經嘗試和編輯了大約2個小時),但是我只知道必須有一種方法。

如果有人可以向我指出正確的方向,那么下面將提供相關代碼!

編輯:更新的代碼,仍然遇到問題

現在,我在調試日志中收到此錯誤:

System.Windows.Data Error: 40 : BindingExpression path error: 'Image' property not found on 'object' ''ContentPresenter' (Name='')'. BindingExpression:Path=Image; DataItem='ContentPresenter' (Name=''); target element is 'Image' (Name=''); target property is 'Source' (type 'ImageSource')

ImageButton.cs(感謝Viv):

class ImageButton : Button
{
    public static readonly DependencyProperty ImageProperty =
        DependencyProperty.Register("Image", typeof(ImageSource), typeof(ImageButton),
        new FrameworkPropertyMetadata(null,
            FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender));

    public ImageSource Image
    {
        get { return (ImageSource)GetValue(ImageProperty); }
        set { SetValue(ImageProperty, value); }
    }
}

ImageButton樣式:

<Style TargetType="{x:Type Controls:ImageButton}" x:Key="FormIconDropDownButton">
    <Setter Property="Margin" Value="5" />
    <Setter Property="Padding" Value="10,5,4,5" />
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate DataType="{x:Type Controls:ImageButton}">
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                        <ColumnDefinition Width="Auto" />
                    </Grid.ColumnDefinitions>

                    <Image Style="{StaticResource FormButtonIcon-Small}"
                           Source="{Binding Image, RelativeSource={RelativeSource TemplatedParent}}"/>

                    <TextBlock Grid.Column="1"
                                Text="{Binding Content, RelativeSource={RelativeSource TemplatedParent}}"
                               VerticalAlignment="Center"
                               Margin="0,0,9,0"/>

                    <Path Grid.Column="2"
                          Fill="Black" 
                          Data="M 0 0 L 3.5 4 L 7 0 Z"
                          VerticalAlignment="Center"/>
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

在窗口xaml中:

<Controls:ImageButton Content="Hello"
                              Style="{StaticResource FormIconDropDownButton}"
                              Image="{StaticResource Icon-Small-Locations}" />

您在xaml中使用的控件類型錯誤。 您仍在使用基類而不是派生類。

另外,您聲明的是依賴項屬性,而不是附加屬性。

附加屬性通過DependencyProperty.RegisterAttached(...)注冊

現在,您需要在xaml中定義IconButton類的位置添加一個名稱空間,例如

xmlns:local="clr-namespace:Mynamespace"

然后切換

{x:Type Button}{x:Type local:IconButton}

<Button ...> to <local:IconButton ...>

我不建議為此tbh附加屬性。 當附加屬性不應該只是我的意見時,它們會被過度使用。

選中此線程以了解DP和AP用法之間的某些差異。 在這種情況下,它是顯示Image的自定義Button 使其比均質化更獨特。

更新:

使用具有常規DP的Button派生類( ImageButton下載鏈接

一切看起來都是正確的,除了您尚未聲明附加屬性。 相反,您只是在IconButton類上聲明了一個普通的DependencyProperty ,然后僅對IconButton或從其派生的類有效。 附加屬性的聲明(可以在任何類型上設置)都使用不同的調用進行注冊,並且還使用get / set方法而不是wrapper屬性:

    public static readonly DependencyProperty ImageProperty =
        DependencyProperty.RegisterAttached(
        "Image",
        typeof(ImageSource),
        typeof(IconButton),
        new FrameworkPropertyMetadata(null,
            FrameworkPropertyMetadataOptions.Inherits | FrameworkPropertyMetadataOptions.AffectsRender));

    public static ImageSource GetImage(DependencyObject target)
    {
        return (ImageSource)target.GetValue(ImageProperty);
    }

    public static void SetImage(DependencyObject target, ImageSource value)
    {
        target.SetValue(ImageProperty, value);
    }

這是我擴展基礎類的示例,在Style和View中使用Dependency Properties。 有關更多詳細信息,請寫在這篇文章中。

public class ItemsList : ListView {
      public static readonly DependencyProperty ItemIconProperty = DependencyProperty.Register("ItemIcon", typeof(ImageSource), typeof(ItemsList));
      public ImageSource ItemIcon {
         get { return (ImageSource)GetValue(ItemIconProperty); }
         set { SetValue(ItemIconProperty, value); }
      }  

      public static readonly DependencyProperty DoubleClickCommandProperty = DependencyProperty.Register("DoubleClickCommand", typeof(ICommand), typeof(ItemsList));
      public ControlTemplate DoubleClickCommand {
         get { return (ControlTemplate)GetValue(DoubleClickCommandProperty); }
         set { SetValue(DoubleClickCommandProperty, value); }
      }
}

/ 擴展ItemList的樣式,其中聲明了'ItemIcon'DependencyProperty /

<Style x:Key="BaseDataSourcesWindowListMenuStyle" TargetType="Controls:ItemsList">    
    <Setter Property="ItemIcon" Value="/Presentation.Shared;component/Resources/Images/data_yellow.png" />    
  </Style>

  <Style x:Key="DataSourcesListMenuStyle" TargetType="Controls:ItemsList"
         BasedOn="{StaticResource BaseDataSourcesWindowListMenuStyle}">    
    <Setter Property="DoubleClickCommand" Value="{Binding Path=VmCommands.EditDataSourceDBCommand}" />
  </Style>

/ 我如何在視圖上使用'ItemIcon'DependencyProperty /

<Controls:ItemsList Grid.Column="0" Grid.Row="1" Margin="8" ItemsSource="{Binding DataSourceDbs}"
                        Style="{DynamicResource DataSourcesListMenuStyle}"
                        SelectedItem="{Binding SelectedDataSourceDB, Mode=TwoWay}" />

首先,我認為這是您在其中聲明的依賴項屬性,它屬於IconButton自定義控件,因此您嘗試在Button控件上使用它。

請參閱http://msdn.microsoft.com/zh-cn/library/ms749011.aspx,以獲取有關如何聲明附加屬性的參考,並將該屬性分配給Button類而不是IconButton,因為您沒有使用該自定義控件在上面的代碼中。

暫無
暫無

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

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