2014-11-05 30 views
1

我想要什麼:後備從一個的DependencyProperty到另一個如果不設置

我創建了一個用戶控件ImageButton,那裏的圖像可以在WPF中進行設置。通常,我將所有狀態的默認圖像重新用於其中一個,但必須以非常詳細的方式配置控件(請參閱下面的WPF剪切)。我想實現的是,沒有設置的每個圖像只使用默認圖像。

我有什麼:

這是我描述ImageButton此刻的方式:

<cc:ImageButton x:Name="cmdHideCustomWindowingArea" 
       DefaultImage="/Images/UI/ButtonDefault.png" 
       HoverImage="/Images/UI/ButtonDefault.png" 
       DownImage="/Images/UI/ButtonActive.png" 
       UpImage="/Images/UI/ButtonDefault.png" 
       DisabledImage="/Images/UI/ButtonDefault.png"/> 

這是使用樣式IM:

<Style TargetType="{x:Type cc:ImageButton}"> 
    <Setter Property="Template" > 
    <Setter.Value> 
     <ControlTemplate TargetType="{x:Type cc:ImageButton}"> 
     <Grid x:Name="Grid"> 
      <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"> 
      <Image x:Name="ButtonImage" Source="{Binding DefaultImage, RelativeSource={RelativeSource TemplatedParent}}"/> 
      <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True" /> 
      </StackPanel> 
     </Grid> 
     <ControlTemplate.Triggers> 
      <Trigger Property="IsMouseOver" Value="true"> 
      <Setter TargetName="ButtonImage" Property="Source" Value="{Binding HoverImage, RelativeSource={RelativeSource TemplatedParent}}" /> 
      </Trigger> 
      <Trigger Property="IsPressed" Value="true"> 
      <Setter TargetName="ButtonImage" Property="Source" Value="{Binding DownImage, RelativeSource={RelativeSource TemplatedParent}}" /> 
      </Trigger> 
      <Trigger Property="IsEnabled" Value="false"> 
      <Setter TargetName="ButtonImage" Property="Source" Value="{Binding DisabledImage, RelativeSource={RelativeSource TemplatedParent}}" /> 
      </Trigger> 
     </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

而且這是代碼:

public class ImageButton : Button 
{ 
    static ImageButton() 
    { 
     DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), 
      new FrameworkPropertyMetadata(typeof(ImageButton))); 
    } 

    public ImageSource DefaultImage 
    { 
     get { return (ImageSource)GetValue(DefaultImageProperty); } 
     set { SetValue(DefaultImageProperty, value); } 
    } 
    public static readonly DependencyProperty DefaultImageProperty = 
     DependencyProperty.Register("DefaultImage", 
     typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(null)); 

    public ImageSource HoverImage 
    { 
     get { return (ImageSource)GetValue(HoverImageProperty); } 
     set { SetValue(HoverImageProperty, value); } 
    } 
    public static readonly DependencyProperty HoverImageProperty = 
     DependencyProperty.Register("HoverImage", 
     typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(null)); 

    // 
    // ... and so on for every state (Down, Up, Disabled) 
    // 
} 

我試過到目前爲止:

我已經嘗試過檢查,如果圖像設置這樣的,它不工作,代碼似乎從來沒有達到吸氣可言。 ..

get { return (ImageSource)GetValue(HoverImageProperty) ?? DefaultImage; } 

2.此外,設置一個TargetNullValue像推薦here不起作用( 「成員 」TargetNullValue「 不被識別或不可訪問。」):

<Trigger Property="IsPressed" Value="true"> 
    <Setter TargetName="ButtonImage" Property="Source" 
      Value="{Binding DownImage, RelativeSource={RelativeSource TemplatedParent}}" 
      TargetNullValue="{Binding DefaultImage, RelativeSource={RelativeSource TemplatedParent}}"/> 
</Trigger> 

我做的最後一件事是試圖建立一個PriorityBinding,如推薦here

<Trigger Property="IsMouseOver" Value="true"> 
    <Setter TargetName="ButtonImage" Property="Source"> 
     <Setter.Value> 
      <PriorityBinding> 
       <Binding Path="{Binding HoverImage, RelativeSource={RelativeSource TemplatedParent}}"/> 
       <Binding Path="{Binding DefaultImage, RelativeSource={RelativeSource TemplatedParent}}"/> 
      </PriorityBinding> 
     </Setter.Value> 
    </Setter> 
</Trigger> 

但返回以下錯誤:

A 'Binding' cannot be set on the 'Path' property of type 'Binding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.

我必須這樣做:

如果我找不到的人沒有設置,那麼回到另一個DependencyProperty的正確方法是什麼?

回答

2

聽起來好像您正在尋找PriorityBinding Class(儘管您之前嘗試使用它)。從鏈接頁面,一個PriorityBinding

Describes a collection of Binding objects that is attached to a single binding target property, which receives its value from the first binding in the collection that produces a value successfully.

...

PriorityBinding lets you associate a binding target (target) property with a list of bindings. The first binding that returns a value successfully becomes the active binding.

A binding returns a value successfully if:

1.The path to the binding source resolves successfully.

2.The value converter, if any, is able to convert the resulting value.

3.The resulting value is valid for the target property.

你應該重新安排Binding PathPriorityBinding小號......試試這個來代替:

<PriorityBinding> 
    <Binding Path="HoverImage" RelativeSource="{RelativeSource TemplatedParent}}" /> 
    <Binding Path="DefaultImage" RelativeSource="{RelativeSource TemplatedParent}}" /> 
</PriorityBinding> 

欲瞭解更多信息,您也可以通過WPF Tutorial - Priority Bindings閱讀教程在Tech Pro網站上。


UPDATE >>>

正如你正確地指出的那樣,PriorityBinding的確會接受null爲有效的,返回的值。但是,您可以通過使用自定義IValueConverter實現來解決該問題,該實現在實際值爲null時返回DependencyProperty.UnsetValue

+0

感謝您的建議。這實際上更好一些,它不會再拋出錯誤,但現在按鈕「閃爍」。我認爲一個「null」值可能會被視爲成功,因此buttn會在「null」和默認圖像之間切換...(因爲沒有圖像加載時它沒有大小,所以鼠標不會懸停在它上面,所以它會回到默認值等等) – DIF 2014-11-05 11:08:28

+0

謝謝!使用轉換器取得了訣竅! – DIF 2014-11-05 11:42:29

相關問題