开发者

WPF ListBox of Buttons: how to change selected item on click with XAML

I have a templated 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>

The selected item is updated manually with code behind:

private void SelectCurrentItem(object sender, MouseButtonEventArgs e)
{
    ListBoxItem item = (ListBoxItem) sende开发者_如何转开发r;
    item.IsSelected = true;
}

Is there a way to do this (update selected item on button click) with XAML only ?


Typically you style your DataTemplate to look and respond like a button if that is the effect you want e.g.

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

You may also want to set the ItemContainerStyle to override the default styling for the 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>


The button defined in your DataTemplate will be intercepting the click event before the ListBoxItem can handle it. Remove the ItemContainerStyle and the Button from your DataTemplate.

<ListBox.ItemTemplate> 
  <DataTemplate> 
    <StackPanel> 
     <Image Source="{Binding Icon}" MaxHeight="32" MaxWidth="32"/> 
     <TextBlock Text="{Binding Label}"/> 
    </StackPanel> 
   </DataTemplate> 
 </ListBox.ItemTemplate> 


A ListBox tracks and selects the current item for you, you dont need to do it in code. remove this

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

you are doing work thats done for you out of the box.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜