我正在尝试创建一个带有图标的“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}" />
答案 0 :(得分:3)
您只是在xaml中使用了错误的控件类型。您仍在使用基类而不是派生类。
此外,您还要声明依赖项属性而不是附加属性。
Attached Properties已在DependencyProperty.RegisterAttached(...)
现在,您需要在xaml中定义IconButton
类的位置添加命名空间,例如
xmlns:local="clr-namespace:Mynamespace"
然后切换
的出现次数 {x:Type Button}
至{x:Type local:IconButton}
和
<Button ...> to <local:IconButton ...>
我不建议为这个tbh附加属性。如果附加属性不应该只是我的观点,那就会过度使用。
检查This thread以查看DP和AP使用之间的某些差异。在这种情况下,它是一个显示Button
的自定义Image
。使它独特而不是使该批次均匀化。
<强>更新强>
Download link使用ImageButton
的派生类(Button
)和普通DP。
答案 1 :(得分:1)
除非您没有声明附属财产,否则一切看起来都是正确的。相反,您只是在DependencyProperty
类上声明了一个正常的IconButton
,然后只能在IconButton
或从它派生的类上设置。附加属性的声明(可以在任何类型上设置)使用不同的调用来注册,并使用get / set方法而不是包装器属性:
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);
}
答案 2 :(得分:1)
这是我扩展基类的示例,在样式和视图中使用依赖项属性。 有关详细信息,请写在这篇文章中。
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}" />
答案 3 :(得分:0)
首先,我认为这是你在那里声明的依赖属性,它属于IconButton自定义控件,你试图在Button控件上使用它。
有关如何声明附加属性的参考,请参阅http://msdn.microsoft.com/en-us/library/ms749011.aspx,并将该属性分配给Button类而不是IconButton,因为您在上面的代码中没有使用该自定义控件。