【问题标题】:How to change selected item of listbox when clicking on the Button / textbox in ItemTemplate?单击ItemTemplate中的按钮/文本框时如何更改列表框的选定项?
【发布时间】:2017-03-28 10:17:41
【问题描述】:

在 WPF 项目中,我有一个 ListBox,其 ItemsSource 绑定到一组项目。我在ListBoxItemTemplate 中使用DataTemplate 来表示这些项目的UI。

我想要发生的是,当用户单击 DataTemplate 的 any 部分以获取绑定项目时,ListBox.SelectedItem 被设置为 DataTemplate 所在的项目。然后将应用选定的Style。从下面的示例代码可以看出,点击标签就可以了。但是,ButtonTextBox 等控件的行为并不理想,毫无疑问还有其他控件。我怀疑这与专注有关。

我怎样才能做到这一点?

XAML:

<Window x:Class="ListViewSelectionOverride.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:ListViewSelectionOverride"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>

    <ListBox ItemsSource="{Binding}">

        <ListBox.Resources>
            <Style TargetType="ListBoxItem">
                <Setter Property="SnapsToDevicePixels" Value="true" />
                <Setter Property="OverridesDefaultStyle" Value="true" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ListBoxItem">
                            <Border
                    Name="Border"
                    Padding="2"
                    SnapsToDevicePixels="true">
                                <ContentPresenter />
                            </Border>
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSelected" Value="true">
                                    <Setter TargetName="Border" Property="BorderBrush" Value="Blue"/>
                                    <Setter TargetName="Border" Property="BorderThickness" Value="1"/>
                                    <Setter Property="FontWeight" Value="Bold" />
                                    <Setter Property="Foreground" Value="Black" />
                                </Trigger>
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.Resources>

        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>

        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border x:Name="itemTemplateBorder">
                    <Grid >
                        <Grid.RowDefinitions>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                            <RowDefinition/>
                        </Grid.RowDefinitions>

                        <Label Margin="3,3,3,0" Grid.Row="0" Content="Label"/>
                        <Button Margin="3,3,3,0" Grid.Row="1" Content="Button"/>
                        <TextBox Margin="3,3,3,0" Grid.Row="2" Text="TextBox"/>
                        <CheckBox Margin="3,3,3,0" Grid.Row="3" Content="CheckBox"/>
                    </Grid>
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>
</Window>

后面的代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Dummy items to generate 4 items in ListBox
        DataContext = new object[] { 1, 2, 3, 4 };
    }
}

【问题讨论】:

    标签: c# wpf xaml listbox


    【解决方案1】:

    您可以为模板中的Border 元素处理PreviewMouseLeftButtonDown 事件并显式选择相应的项目:

    private void Border_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Border border = sender as Border;
        lvv.SelectedItem = border.DataContext;
    }
    

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border Name="Border" Padding="2" SnapsToDevicePixels="true"
    PreviewMouseLeftButtonDown="Border_PreviewMouseLeftButtonDown">
                    <ContentPresenter />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="true">
                        <Setter TargetName="Border" Property="BorderBrush" Value="Blue"/>
                        <Setter TargetName="Border" Property="BorderThickness" Value="1"/>
                        <Setter Property="FontWeight" Value="Bold" />
                        <Setter Property="Foreground" Value="Black" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    

    【讨论】:

    • 嗨@mm8,感谢您的回复。效果很好!干杯。想知道是否有唯一的 XAML 解决方案来避免代码落后?
    猜你喜欢
    • 1970-01-01
    • 2011-06-18
    • 1970-01-01
    • 2018-08-08
    • 1970-01-01
    • 1970-01-01
    • 2016-12-21
    • 1970-01-01
    • 2016-02-21
    相关资源
    最近更新 更多