WPF ListBox of Buttons: как изменить выбранный элемент по клику с помощью XAML - PullRequest
3 голосов
/ 03 февраля 2010

У меня есть шаблон ListBox:

<ListBox Grid.Row="0" Grid.Column="1" Background="Transparent" BorderThickness="0" x:Name="mainMenu"
    ItemsSource="{Binding Source={x:Static local:MenuConfig.MainMenu},  Mode=OneTime}"
   IsSynchronizedWithCurrentItem="True">
 <ListBox.ItemContainerStyle>
  <Style TargetType="ListBoxItem">
   <EventSetter Event="PreviewMouseUp" Handler="SelectCurrentItem"/>
  </Style>
 </ListBox.ItemContainerStyle>
 <ListBox.ItemsPanel>
  <ItemsPanelTemplate>
   <StackPanel Orientation="Horizontal"></StackPanel>
  </ItemsPanelTemplate>
 </ListBox.ItemsPanel>
  <ListBox.ItemTemplate>
  <DataTemplate>
   <Button>
    <StackPanel>
     <Image Source="{Binding Icon}" MaxHeight="32" MaxWidth="32"/>
     <TextBlock Text="{Binding Label}"/>
    </StackPanel>
   </Button>
  </DataTemplate>
 </ListBox.ItemTemplate>
</ListBox>

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

private void SelectCurrentItem(object sender, MouseButtonEventArgs e)
{
    ListBoxItem item = (ListBoxItem) sender;
    item.IsSelected = true;
}

Есть ли способ сделать это (обновить выбранный элемент по нажатию кнопки) только с XAML?

Ответы [ 3 ]

1 голос
/ 04 февраля 2010

Кнопка, указанная в вашем DataTemplate, будет перехватывать событие щелчка, прежде чем ListBoxItem сможет его обработать. Снимите ItemContainerStyle и Button с вашего DataTemplate.

<ListBox.ItemTemplate> 
  <DataTemplate> 
    <StackPanel> 
     <Image Source="{Binding Icon}" MaxHeight="32" MaxWidth="32"/> 
     <TextBlock Text="{Binding Label}"/> 
    </StackPanel> 
   </DataTemplate> 
 </ListBox.ItemTemplate> 
1 голос
/ 05 февраля 2010

Обычно ваш стиль DataTemplate выглядит и реагирует как кнопка, если вы хотите именно такой эффект, например

<ListBox.ItemTemplate>
    <DataTemplate>
        <Border BorderBrush="Black" BorderThickness="3" CornerRadius="10" Background="#FFD6D3D3" Margin="5">
            <Border x:Name="myBorder" BorderBrush="#FFD6D3D3" BorderThickness="4" CornerRadius="10" Padding="2">
                <Border.Background>
                    <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1" >
                        <GradientStop Color="#FFA5A5A5" Offset="1"/>
                        <GradientStop Color="White"/>
                    </LinearGradientBrush>
                </Border.Background>
                <StackPanel>
                    <Image Source="{Binding Icon}" MaxHeight="32" MaxWidth="32"/>
                    <TextBlock x:Name="TxtContent" Text="{Binding Label}"/>
                </StackPanel>
            </Border>
        </Border>
        <DataTemplate.Triggers>
            <DataTrigger Binding="{Binding Path=IsSelected, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}}}" Value="True">
                <Setter TargetName="myBorder" Property="Background">
                    <Setter.Value>
                        <LinearGradientBrush StartPoint="0.5,1" EndPoint="0.5,0">
                            <GradientStop Color="#FFA5A5A5" Offset="1"/>
                            <GradientStop Color="White" />
                        </LinearGradientBrush>
                    </Setter.Value>
                </Setter>
                <Setter TargetName="TxtContent" Property="RenderTransform" >
                    <Setter.Value>
                        <TranslateTransform Y="2.0" />
                    </Setter.Value>
                </Setter>
            </DataTrigger>
        </DataTemplate.Triggers>
    </DataTemplate>
</ListBox.ItemTemplate>

Вы также можете установить ItemContainerStyle, чтобы переопределить стиль по умолчаниюSelectedItem:

<ListBox.ItemContainerStyle>
    <Style TargetType="{x:Type ListBoxItem}" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type ListBoxItem}">
                    <ContentPresenter />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ListBox.ItemContainerStyle>
0 голосов
/ 04 февраля 2010

A ListBox отслеживает и выбирает текущий элемент для вас, вам не нужно делать это в коде.удалите это

 <ListBox.ItemContainerStyle>
  <Style TargetType="ListBoxItem">
   <EventSetter Event="PreviewMouseUp" Handler="SelectCurrentItem"/>
  </Style>
 </ListBox.ItemContainerStyle>

вы делаете работу, которая сделана для вас из коробки.

...