2009-10-20 124 views
3

我想为我新建的用户控件设置一个自定义样式,但是我收到错误:“无法将属性'属性'中的值转换为类型的对象'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> 

回答

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 
} 
与正确注册依赖属性

希望这将有助于你缩小问题(甚至修复它)

+0

谢谢,我想我快到了。我不得不重新修改ImageSource_PropertyChanged来构建它,也许这是它出错的地方?但我的样式(我现在已添加上面看到)不适用于我的按钮,当它被设置为禁用。有任何想法吗? private static void ImageSource_PropertyChanged(DependencyObject source,DependencyPropertyChangedEventArgs e) {((MyButton)source).tehImage.Source =(ImageSource)e.NewValue; } – 4imble 2009-10-21 11:57:54

4
我看到

最大的问题是,你注册财产Image而不是所拥有您的UserControl。更改为:

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

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

+0

这似乎已经停止了我的风格现在发生的错误,但它现在停止我的usercontrol从工作,它已经从它使用的所有地方消失。我已经添加了usercontrol的Xaml。 – 4imble 2009-10-20 10:18:33

1

设置的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> 
0

实现源的正确方法对于我认为用户控件中的图像不是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); 
}