依赖属性不起作用,尝试通过样式设置器进行设置

时间:2009-10-20 09:44:30

标签: wpf xaml styles dependency-properties

我正在尝试为新建的usercontrol设置自定义样式,但是我收到错误:“无法将属性'Property'中的值转换为'System.Windows.DependencyProperty'类型的对象。”

我以为我已经设置了依赖属性,但似乎情况并非如此,所以我做了一些研究并补充说:

   public static readonly DependencyProperty ImageSourceProperty = 
   DependencyProperty.Register("ImageSource", typeof(BitmapSource), typeof(Image));

这样做: - MyButton.Xaml.Cs -

    namespace Client.Usercontrols
{
    public partial class MyButton : UserControl
    {
        public static readonly DependencyProperty ImageSourceProperty = 
            DependencyProperty.Register("ImageSource", typeof(BitmapSource), typeof(Image));

        public MyButton()
        {
            InitializeComponent();            
        }


        public event RoutedEventHandler Click;

        void onButtonClick(object sender, RoutedEventArgs e)
        {
            if (this.Click != null)
                this.Click(this, e);
        }

        BitmapSource _imageSource;
        public BitmapSource ImageSource
        {
            get { return _imageSource; }
            set
            {
                _imageSource = value;
                tehImage.Source = _imageSource;
            }
        }
    }
}

遗憾的是,这不起作用。我也试过这个:

public BitmapSource ImageSource
{
    get { return (BitmapSource)GetValue(MyButton.ImageSourceProperty); }
    set
    {
        SetValue(ImageSourceProperty, value);
    }
}

但是这不起作用,图像没有显示,并产生与之前提到的相同的错误。

有什么想法吗? 关心Kohan。

- MyButton.Xaml -

<UserControl x:Class="Client.Usercontrols.MyButton"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" MinHeight="30" MinWidth="40"
    DataContext="{Binding RelativeSource={RelativeSource Self}}">


    <Button Width="Auto" HorizontalAlignment="Center" Click="onButtonClick">

        <Border CornerRadius="5" BorderThickness="1" BorderBrush="Transparent" >
            <Grid>
                <Image Name="tehImage" Source="{Binding ImageSource}" />
                <TextBlock Name="tehText" Text="{Binding Text}" Style="{DynamicResource ButtonText}" />
            </Grid>
        </Border>

    </Button>
</UserControl>

- MYButton风格 -

<Style TargetType="{x:Type my:MyButton}" >
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type my:MyButton}">
                <ContentPresenter />
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="ImageSource" Value="../Images/Disabled.png" />                        
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

4 个答案:

答案 0 :(得分:4)

我看到的最大问题是您将该属性注册为Image所有,而不是UserControl。改为:

public static readonly DependencyProperty ImageSourceProperty = 
            DependencyProperty.Register("ImageSource", typeof(BitmapSource), typeof(MyButton));

如果这不起作用,则需要查看您的XAML。

答案 1 :(得分:3)

依赖项属性的标准格式是(我已在您的信息中添加):

public BitmapSource ImageSource
{
    get { return (BitmapSource)GetValue(ImageSourceProperty); }
    set { SetValue(ImageSourceProperty, value); }
}

/* Using a DependencyProperty as the backing store for ImageSource. 
   This enables animation, styling, binding, etc... */

public static readonly DependencyProperty ImageSourceProperty =
        DependencyProperty.Register("ImageSource", 
            typeof(BitmapSource), 
            typeof(MyButton), 
            new UIPropertyMetadata(null)
        );

看起来你也试图将依赖属性传递给名为“tehImage”的对象的ImageSource。您可以将其设置为使用PropertyChangedCallback自动更新...这意味着每当更新属性时,这将自动调用更新。

因此属性代码变为:

public BitmapSource ImageSource
{
    get { return (BitmapSource)GetValue(ImageSourceProperty); }
    set { SetValue(ImageSourceProperty, value); }
}

/* Using a DependencyProperty as the backing store for ImageSource.  
   This enables animation, styling, binding, etc... */

public static readonly DependencyProperty ImageSourceProperty =
        DependencyProperty.Register("ImageSource", 
            typeof(BitmapSource), typeof(MyButton), 
            new UIPropertyMetadata(null, 
                ImageSource_PropertyChanged
            )
        );

private static void ImageSource_PropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
    ((MyButton)source).tehImage.ImageSource = (ImageSource)e.NewValue
}

希望通过正确注册的依赖项属性,这将帮助您缩小问题范围(甚至修复它)

答案 2 :(得分:1)

为UserControl设置DataContext:

public MyButton()
{
    InitializeComponent();
    DataContext = this;
}

或者,如果您不能这样做(例如,因为DataContext设置为另一个对象),您可以在XAML中执行此操作:

<UserControl x:Class="Client.Usercontrols.MyButton"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" MinHeight="30" MinWidth="40"
    DataContext="{Binding RelativeSource={RelativeSource Self}}"
    x:Name="MyControl">


    <Button Width="Auto" HorizontalAlignment="Center" Click="onButtonClick">

        <Border CornerRadius="5" BorderThickness="1" BorderBrush="Transparent" >
            <Grid>
                <Image Name="tehImage" Source="{Binding ElementName=MyControl, Path=ImageSource}" />
                <TextBlock Name="tehText" Text="{Binding ElementName=MyControl, Path=Text}" Style="{DynamicResource ButtonText}" />
            </Grid>
        </Border>

    </Button>
</UserControl>

答案 3 :(得分:0)

在我看来,在用户控件中实现Image的源的正确方法不是BitmapSouce。最简单和最好的方式(再次根据我的说法)是使用Uri。

将您的依赖项属性更改为此(同时还定义更改回调事件):

ImageSourceProperty = DependencyProperty.Register(
    "ImageSource", typeof (Uri), typeof (MyButton),
    new FrameworkPropertyMetadata(new PropertyChangedCallback(OnImageSourceChanged)));

以及此属性:

public Uri ImageSource
{
    get
    {
           return (Uri)GetValue(ImageSourceProperty);
    }
    set
    {
           SetValue(ImageSourceProperty, value);
    }
}

你的回电是这样的:

private static void OnImageSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
    MyButton hsb = (MyButton)sender;

    Image image = hsb.tehImage;
    image.Source = new BitmapImage((Uri) e.NewValue);
}