Проблемы с дизайном ListBoxItem ControlTemplate в WPF? - PullRequest
0 голосов
/ 09 марта 2011

Вот мой XAML:

<ListBox 
  Name="PlaylistListBox" 
  ScrollViewer.CanContentScroll="False" 
  HorizontalContentAlignment="Stretch" 
  ItemsSource="{Binding Source={StaticResource ResourceKey=MyListBoxView}}" 
  ItemTemplateSelector="{Binding Source={StaticResource ResourceKey=MySelector}}" 
  MouseDoubleClick="PlaylistListBox_MouseDoubleClick" >
  <ListBox.ItemContainerStyle> 
    <Style TargetType="ListBoxItem">
      <Setter Property="SnapsToDevicePixels" Value="true"/>
      <Setter Property="OverridesDefaultStyle" Value="true"/>
      <Setter Property="Template"> 
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem"> 
            <Border 
              Name="Border" 
              CornerRadius="4" 
              SnapsToDevicePixels="true">
              <ContentPresenter />
            </Border>
            <ControlTemplate.Triggers>
              <Trigger Property="IsSelected" Value="true">
                <Setter TargetName="Border" Property="Background" Value="Black" />

                <!-- The following setter for opacity is giving me headaches -->
                <Setter TargetName="Border" Property="Opacity" Value="0.5" />

              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
      <EventSetter 
        Event="Loaded" 
        Handler="PlaylistListBoxItem_Loaded" />
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>

Два выпуска:

  1. Из-за установки Opacity весь элемент прозрачен на 50%. Я хочу только граница, определенная в ListBoxItem ControlTemplate, должна быть прозрачной, а ее содержимое сохранить полную непрозрачность.
  2. Как сделать сеттер / триггер так, чтобы эта граница была красной, если ListBox не в фокусе? Это должно быть что-то вроде InFocus="False" и IsSelected="True".

Спасибо за разъяснения.

1 Ответ

2 голосов
/ 09 марта 2011
  1. Вы должны поместить еще одну рамку под контент и сделать его полупрозрачным, оставляя основной контент полностью видимым. Вы можете сделать это, используя Grid и поместив сначала «фоновую» границу, а затем содержимое. Таким образом, вы установите непрозрачность только на границе фона, но не на контенте;

  2. Для этого вы можете использовать MultiTrigger.

Вот измененный стиль, который показывает, что я имею в виду:

<ListBox 
  Name="PlaylistListBox" 
  ScrollViewer.CanContentScroll="False" 
  HorizontalContentAlignment="Stretch" 
  ItemsSource="{Binding Source={StaticResource ResourceKey=MyListBoxView}}" 
  ItemTemplateSelector="{Binding Source={StaticResource ResourceKey=MySelector}}" 
  MouseDoubleClick="PlaylistListBox_MouseDoubleClick" >
  <ListBox.ItemContainerStyle> 
    <Style TargetType="ListBoxItem">
      <Setter Property="SnapsToDevicePixels" Value="true"/>
      <Setter Property="OverridesDefaultStyle" Value="true"/>
      <Setter Property="Template"> 
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem"> 
            <Grid>
              <Border 
                 Name="BackgroundBorder" 
                 CornerRadius="4" 
                 SnapsToDevicePixels="true">                 
              </Border>
              <Border Name="Border">
                 <ContentPresenter />
              </Border>
            </Grid>
            <ControlTemplate.Triggers>
              <Trigger Property="IsSelected" Value="true">
                <Setter TargetName="BackgroundBorder" Property="Background" Value="Black" />

                <!-- The following setter for opacity is giving me headaches -->
                <Setter TargetName="BackgroundBorder" Property="Opacity" Value="0.5" />

              </Trigger>
              <MultiTrigger>
                 <MultiTrigger.Conditions>
                      <Condition Property="IsSelected" Value="True"/>
                      <Condition Property="IsFocused" Value="False"/>
                 </MultiTrigger.Conditions>
                 <Setter TargetName="BackgroundBorder" Property="Background" Value="Red" />
              </MultiTrigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
      <EventSetter 
        Event="Loaded" 
        Handler="PlaylistListBoxItem_Loaded" />
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>
...