Настройка состояния переключения кнопки переключения в wpf - PullRequest
8 голосов
/ 07 октября 2009

Я хочу настроить состояние переключателя в 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, он не работает (работает только для одного такого элемента). Пожалуйста, скажите мне, иду ли я в правильном направлении. Также расскажи мне другие способы достижения этого.

Ответы [ 4 ]

10 голосов
/ 07 октября 2009

Проблема здесь в том, что вы используете 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 - количество элементов в вашем списке.)

5 голосов
/ 07 октября 2009

Этот ответ поможет вам. Там я взял ToggleButton и создал его так, чтобы он выглядел как ToggleButton в TreeView (+ / - часть для расширения узлов свертывания). Вам просто нужно изменить пути, которые рисуют знаки - и +, чтобы вместо этого показывать ваши изображения.

Здесь все персонализировано, просто поместите изображение с именем "on.jpg", а другое - с именем off.jpg в каталог C: \, и оно должно работать, просто скопировав / вставив в окно: *

    <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>
3 голосов
/ 22 марта 2012

Вот кнопка ToggleButton с 3 изображениями и всплывающим окном:

  1. Изображение, когда IsChecked = false.
  2. Изображение, когда IsChecked = true.
  3. Изображение для случая, когда IsMouseOver = true.

Изображения хранятся в ресурсах как BitmapImage, чтобы избежать изменения визуалов на триггерах.

Файлы изображений должны быть добавлены в ресурсы, а затем файлы, добавленные в папку «Resoruces» в проекте, должны быть отмечены как BuildAction = Resource .

Также применяет прозрачность к элементу управления изображением, когда ToggleButton IsEnabled = false;

Код:

    <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>
1 голос
/ 07 октября 2009

Как сказал Дрю Ноакс, в моем фрагменте было только два изображения. Так что только два пункта работали правильно. Я решил эту проблему с помощью следующего фрагмента.

<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>

Просто, я переместил триггеры в шаблон данных. Не знаю, правильный ли это ответ? Кажется, работает

...