2012-11-05 80 views
0

我無法通過單擊此按鈕(在其內容中有圖像)正確更改ImageSource。這是我的Xaml和Code Behind。2狀態WPF按鈕不變ImageSource

XAML:

<Window.Resources> 
    <Style x:Key="NoChromeButton" TargetType="{x:Type Button}"> 
     <Setter Property="Background" Value="Transparent"/> 
     <Setter Property="BorderThickness" Value="1"/> 
     <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 
     <Setter Property="HorizontalContentAlignment" Value="Center"/> 
     <Setter Property="VerticalContentAlignment" Value="Center"/> 
     <Setter Property="Padding" Value="1"/> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Button}"> 
        <Grid x:Name="Chrome" Background="{TemplateBinding Background}" SnapsToDevicePixels="true"> 
         <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> 
        </Grid> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsEnabled" Value="false"> 
          <Setter Property="Foreground" Value="#ADADAD"/> 
          <Setter Property="Opacity" TargetName="Chrome" Value="0.5"/> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

<Grid> 
    <Button x:Name="DrawCircleButton" Height="56" Width="157" 
    Margin="10,10,0,0" VerticalAlignment="Top" 
    HorizontalAlignment="Left" Click="DrawCircleButtonClick" 
      Style="{DynamicResource NoChromeButton}" 
    > 
     <Image x:Name="imgButtonState" > 
      <Image.Source> 
       <BitmapImage UriSource="Resources/off.gif" /> 
      </Image.Source> 
     </Image> 
    </Button> 
    <ScrollViewer Margin="0,50,0,0"> 
     <TextBlock Name="textBlock1" TextWrapping="Wrap" FontSize="20" FontWeight="Bold" /> 
    </ScrollViewer> 


</Grid> 

代碼背後:

private void DrawCircleButtonClick(object sender, RoutedEventArgs e) 
    { 
     var t = ButtonState; 
     ButtonState = t; 
    } 

public bool ButtonState 
    { 
     get 
     { 
      return (bool)GetValue(ButtonStateProperty); 
     } 
     set 
     { 
      var t = new BitmapImage(new Uri("Resource/on.gif", UriKind.Relative)); 

      DrawCircleButton.Content = !value ? imgButtonState.Source = new BitmapImage(new Uri("on.gif", UriKind.Relative)) : imgButtonState.Source = new BitmapImage(new Uri("off.gif", UriKind.Relative)); 
      SetValue(ButtonStateProperty, !value); 
     } 
    } 

    public static readonly DependencyProperty ButtonStateProperty = DependencyProperty.Register("ButtonState", typeof(bool), typeof(bool)); 

所以最初,該按鈕被設置爲 '關閉'。但是當它被點擊時,它會在'開'和'關'之間切換。我確信我做了錯誤的事情,因爲顯示的內容是文本到圖像的路徑。有任何想法嗎?

回答

1

首先,WPF也有一個ToggleButton。也許在這裏可能更合適。

現在你的錯誤。它基本上在以下行中:

DrawCircleButton.Content = !value ? imgButtonState.Source = new BitmapImage(new Uri("on.gif", UriKind.Relative)) : imgButtonState.Source = new BitmapImage(new Uri("off.gif", UriKind.Relative)); 

您將一個新的BitmapImage分配給Button的Content屬性。由於Button的ContentPresenter無法處理該類型,因此它只顯示ToString()的結果。如果您只是放棄作業並編寫以下內容,它將起作用。內容不會更改,只是已經是Button內容的圖像的來源。

imgButtonState.Source = value 
    ? new BitmapImage(new Uri("on.gif", UriKind.Relative)) 
    : new BitmapImage(new Uri("off.gif", UriKind.Relative)); 

然而,依賴屬性ButtonState的定義仍然存在嚴重問題。如果你想它定義成這樣,你就必須從按鈕派生並寫聲明象下面這樣:

public class MyButton : Button 
{ 
    public static readonly DependencyProperty ButtonStateProperty = 
     DependencyProperty.Register(
      "ButtonState", typeof(bool), typeof(MyButton), 
      new FrameworkPropertyMetadata(ButtonStatePropertyChanged)); 

    public bool ButtonState 
    { 
     get { return (bool)GetValue(ButtonStateProperty); } 
     set { SetValue(ButtonStateProperty, value); } 
    } 

    private static void ButtonStatePropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) 
    { 
     ((MyButton)obj).imgButtonState.Source = (bool)e.NewValue 
      ? new BitmapImage(new Uri("on.gif", UriKind.Relative)) 
      : new BitmapImage(new Uri("off.gif", UriKind.Relative)); 
    } 
} 

你也應該不會做別的指望依賴項屬性的CLR包裝的GetValue /的SetValue。相反,你應該使用一個PropertyChangedCallback,如上所示。請參閱Checklist for Defining a Dependency Property中實施包裝部分。

如果您不想從Button派生,您可以將ButtonState定義爲attached property

+0

謝謝你的詳細迴應克萊門斯。它工作,但我想知道,在你的第二個代碼塊中,包含按鈕的XAML是否有點擊事件?我試着使用你提供的代碼,並將'MyButton'改爲我在XAML中定義的按鈕。 – Jason

+0

當然可以。派生的MyButton繼承了Button中的所有屬性,方法和事件。它可以用於任何可以使用Button的地方。在XAML中,用'替換'

0

使用Image而不是BitmapImage作爲Button的內容。此外,使用Image.Source = "/Resources/YourFile.png"而不是在XAML和代碼中聲明bitmapimage。