2009-10-07 124 views
8

我想自定義wpf中切換按鈕的切換狀態。我想在開啓按鈕時將圖像設置爲切換按鈕,並在關閉時設置另一個圖像。爲此,我想到了使用觸發器。這就是我最終做的,自定義wpf中的切換按鈕的切換狀態

<Window ...> 
    <Window.Resources> 
     <Image x:Key="OnImage" Source="C:\ON.jpg" /> 
     <Image x:Key="OffImage" Source="C:\OFF.jpg" /> 
     <Style x:Key="OnOffToggleImageStyle" TargetType="ToggleButton"> 
      <Style.Triggers> 
       <Trigger Property="IsChecked" Value="True"> 
        <Setter Property="Content" Value="{StaticResource OnImage}" /> 
       </Trigger> 
       <Trigger Property="IsChecked" Value="False"> 
        <Setter Property="Content" Value="{StaticResource OffImage}" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </Window.Resources> 
    <ListBox> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       ... 
       <ToggleButton IsChecked="{Binding Status}" Width="100" Height="35" Style="{StaticResource OnOffToggleImageStyle}" /> 
       ... 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
</Window> 

上面的代碼似乎只適用於列表框中的兩個項目。如果多個項目具有綁定值,狀態爲true,則不起作用(僅適用於一個此類項目)。請告訴我我是否正朝着正確的方向前進。另外告訴我其他方法來實現這一點。

回答

10

這裏的問題是因爲您正在使用Image資源。您資源中的Image是控件的具體實例。它一次只能在一個地方。所以,當你的列表中有多個項目......

這應該爲你工作:

<Style x:Key="OnOffToggleImageStyle" TargetType="ToggleButton"> 
<Style.Triggers> 
    <Trigger Property="IsChecked" Value="True"> 
    <Setter Property="Content"> 
     <Setter.Value> 
     <Image Source="C:\ON.jpg" /> 
     </Setter.Value> 
    </Setter> 
    </Trigger> 
    <Trigger Property="IsChecked" Value="False"> 
    <Setter Property="Content"> 
     <Setter.Value> 
     <Image Source="C:\OFF.jpg" /> 
     </Setter.Value> 
    </Setter> 
    </Trigger> 
</Style.Triggers> 
</Style> 

注意,您可以通過使用ImageSource在每個圖像文件提高該性能的資源,然後參考Image。這實際上意味着每張圖片只能從磁盤加載一次,而不是2 * N次(其中N是列表中的項目數)。

+3

上面代碼段拋出異常。以下是詳細信息, 無法將'System.Windows.Controls.Image'類型的內容添加到'System.Object'類型的對象。標記文件 – sudarsanyes 2009-10-07 16:22:41

+1

中的對象'System.Windows.Controls.Image'出錯這非常有幫助。 :)謝謝.. – 2011-03-30 07:43:39

5

This answer會幫助您。在那裏,我使用了一個ToggleButton並將其設置爲TreeView中的ToggleButton(用於展開摺疊節點的+/- 部分)。您只需更改繪製 - 和+號的路徑,即可顯示圖像。

這裏去個性化你的,只是把所謂的「on.jpg」的圖像,另一個你的C下稱「off.jpg」:\目錄下,它應該工作的只是複製/粘貼到你的窗口:

<Window.Resources> 
     <SolidColorBrush x:Key="GlyphBrush" Color="#444" /> 
     <ControlTemplate x:Key="toggleButtonTemplate" TargetType="ToggleButton"> 
      <Grid 
       Width="15" 
       Height="13" 
       Background="Transparent"> 
       <Image x:Name="ExpandImage" 
         Source="C:\off.jpg" 
         HorizontalAlignment="Left" 
         VerticalAlignment="Center" 
         Margin="1,1,1,1" />      
      </Grid> 
      <ControlTemplate.Triggers> 
       <Trigger Property="IsChecked" 
        Value="True"> 
        <Setter Property="Source" 
         TargetName="ExpandImage" 
         Value="C:\on.jpg"/> 
       </Trigger> 
      </ControlTemplate.Triggers> 
     </ControlTemplate> 
     <Style x:Key="toggleButtonStyle" TargetType="ToggleButton"> 
      <Setter Property="Template" Value="{StaticResource toggleButtonTemplate}" /> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <ToggleButton Style="{StaticResource toggleButtonStyle}" /> 
    </Grid> 
+0

什麼是ExpandImage在上面的片段?沒有稱爲ExpandImage的觸發器類型。你能檢查一下嗎? – sudarsanyes 2009-10-07 16:47:40

+0

模板內部圖像的名稱:。這樣ControlTemplate就可以訪問它並修改其屬性: Carlo 2009-10-07 17:13:28

+0

對不起,我沒有完整閱讀。謝謝。它的工作現在。爲什麼它不適合我?爲什麼只有一次? – sudarsanyes 2009-10-07 17:32:34

1

像德魯諾克斯說的,在我的snippte中只有兩個圖像。所以只有兩個項目正常工作。我用下面的代碼解決了這個問題。

<ToggleButton 
    Grid.Row="0" Grid.Column="2" Grid.RowSpan="2" 
    VerticalAlignment="Center" HorizontalAlignment="Center" 
    IsChecked="{Binding Status}" 
    Width="100" Height="35"> 
    <ToggleButton.Resources> 
    <Image x:Key="OnImage" Source="C:\ON.jpg" /> 
    <Image x:Key="OffImage" Source="C:\OFF.jpg" /> 
    </ToggleButton.Resources> 
    <ToggleButton.Style> 
    <Style TargetType="ToggleButton"> 
     <Style.Triggers> 
     <Trigger Property="IsChecked" Value="True"> 
      <Setter Property="Content" Value="{StaticResource OnImage}"> 
      </Setter> 
     </Trigger> 
     <Trigger Property="IsChecked" Value="False"> 
      <Setter Property="Content" Value="{StaticResource OffImage}"> 
      </Setter> 
     </Trigger> 
     </Style.Triggers> 
    </Style> 
    </ToggleButton.Style> 
</ToggleButton> 

簡單,我將觸發器移入數據模板中。不知道這是否是你正確的答案。似乎是工作

+0

有趣的是,我得到錯誤「System.Windows.Controls.Image」不是'Setter.Value'的有效值;從Visual或ContentElement派生的值不受支持。 – 2010-02-02 23:47:40

+0

感謝您發表該答案。 – Tony 2011-11-04 00:06:04

3

這裏是一個切換按鈕3倍的圖像和一個彈出:

  1. 一種圖像時器isChecked =假。
  2. IsChecked = true時的圖像。
  3. IsMouseOver = true時的圖像。

圖像以BitmapImage的形式存儲在資源中,以避免更改視頻對象。

必須將圖像文件添加到資源中,然後添加到項目中「Resoruces」文件夾的文件必須標記爲BuildAction =資源

當ToggleButton IsEnabled = false時,它也對Image控件應用不透明度;

代碼:

<ToggleButton 
     x:Name="btnToggleImage" 
     Margin="5" 
     Width="50"    
     Height="50" 
     > 
     <ToggleButton.Resources> 
      <BitmapImage x:Key="imgNormal" UriSource="/YOURPROJECTNAME;component/Resources/YourUncheckedImage.png"/> 
      <BitmapImage x:Key="imgHover" UriSource="/YOURPROJECTNAME;component/Resources/YourHoverImage.png"/> 
      <BitmapImage x:Key="imgChecked" UriSource="/YOURPROJECTNAME;component/Resources/YourCheckedImage.png"/> 
     </ToggleButton.Resources> 

     <ToggleButton.Style> 
      <Style TargetType="ToggleButton"> 
       <Setter Property="Template"> 
        <Setter.Value> 
         <ControlTemplate TargetType="ToggleButton"> 
          <Image 
           x:Name="PART_Image" 
           Source="{StaticResource imgNormal}" 
           /> 
          <ControlTemplate.Triggers> 
           <Trigger Property="IsChecked" Value="true"> 
            <Setter TargetName="PART_Image" Property="Source" Value="{StaticResource imgChecked}"/> 
           </Trigger> 
           <Trigger Property="IsMouseOver" Value="true"> 
            <Setter TargetName="PART_Image" Property="Source" Value="{StaticResource imgHover}"/> 
           </Trigger> 
           <Trigger Property="IsEnabled" Value="false"> 
            <Setter TargetName="PART_Image" Property="Opacity" Value="0.6"/> 
           </Trigger> 
          </ControlTemplate.Triggers> 
         </ControlTemplate> 
        </Setter.Value> 
       </Setter> 
      </Style> 
     </ToggleButton.Style> 
    </ToggleButton>   

    <Popup 
     x:Name="popup1" 
     PlacementTarget="{Binding ElementName=btnToggleImage}" 
     PopupAnimation="Slide" 
     IsOpen="{Binding ElementName=btnToggleImage, Path=IsChecked, Mode=TwoWay}" 
     StaysOpen="False" 
     MinWidth="{Binding ElementName=btnToggleImage, Path=Width}"> 
     <Grid Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"> 
      <!--<ItemsPresenter/>--> 
      <Label Content="Hello Wolrd!"/> 
     </Grid> 
    </Popup>