C# WPF ListView SelectedItem 在失去焦点时保持值

问题描述 投票:0回答:1

问题:当我尝试按下与 ListView 面板不同的另一个面板上的按钮时,失去 ListView 项目焦点并因此重置 SelectedItem 属性。我需要保持焦点(可选)并保持 SelectedItem 值 如果我单击红色边框中的“Test1”值是正确的。但点击“Test3”后它会重置。 ListView 的样式问题。如果在 ListControl.xaml 中删除触发器(请参阅下面的完整代码)

<Trigger Property="IsKeyboardFocusWithin" Value="True">
    <Setter Property="IsSelected" Value="True" />
</Trigger>

这个问题将会得到解决。但在这种情况下,按下“Test1”和“Test2”按钮不会聚焦行,也不会设置 SelectedItem 值。

MainWindow.xaml

<Window x:Class="ListViewSample.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:localVM="clr-namespace:ListViewSample"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <localVM:MainViewModel/>
    </Window.DataContext>
    <Grid>
        <localVM:ListControl></localVM:ListControl>
    </Grid>
</Window>

ListControl.xaml

<UserControl x:Class="ListViewSample.ListControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ListViewSample"
             d:DataContext="{d:DesignInstance Type=local:MainViewModel}"
             mc:Ignorable="d" 
             d:DesignHeight="450"
             d:DesignWidth="500">
    <UserControl.Resources>
        <SolidColorBrush x:Key="WindowBackground" Color="White" Opacity="0.75"/>
        <Style x:Key="ListViewItemStyle" TargetType="ListViewItem">
            <Setter Property="HorizontalContentAlignment" Value="Left" />
            <Style.Triggers>
                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                    <Setter Property="IsSelected" Value="True" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <ListView Grid.Row="0" ItemsSource="{Binding ParametersList}" SelectedItem="{Binding SelectedItem}"  ItemContainerStyle="{StaticResource ListViewItemStyle}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <Button Content="Test1" Margin="5" Height="30" Width="50" Command="{Binding PushButtonPnl}" />
                        <Button Content="Test2" Margin="5" Height="30" Width="50" Command="{Binding PushButtonPnl}" />
                        <TextBlock Text="{Binding Id}" />
                        <TextBlock Text="{Binding Name}" />
                        <TextBlock Text="{Binding Value}" />
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

        <Border x:Name="stkEasyLocatePanel" Grid.Row="0" Margin="5" Padding="5" BorderBrush="Black" BorderThickness="1,1,1,1" CornerRadius="5" Background="{DynamicResource WindowBackground}" Width="400" HorizontalAlignment="Right" >
            <StackPanel>
                <Border Margin="5" Padding="5" BorderBrush="Red" BorderThickness="1,1,1,1" CornerRadius="5">
                    <TextBlock Text="{Binding SelectedItem.Value}" FontSize="40" Foreground="Red" VerticalAlignment="Center"/>
                </Border>
                <StackPanel Orientation="Horizontal">
                    <Ellipse Margin="5" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Stroke="Black" Fill="Red"/>
                    <Ellipse Margin="5" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Stroke="Black" Fill="Orange"/>
                    <Ellipse Margin="5" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Stroke="Black" Fill="Yellow"/>
                    <Ellipse Margin="5" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Stroke="Black" Fill="Green"/>
                    <Ellipse Margin="5" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Stroke="Black" Fill="LightBlue"/>
                    <Ellipse Margin="5" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Stroke="Black" Fill="Blue"/>
                    <Ellipse Margin="5" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Center" Stroke="Black" Fill="Violet"/>
                </StackPanel>
                <StackPanel Orientation="Horizontal">
                    <Button Content="Test3" Margin="5" Height="30" Width="50" Command="{Binding PushButtonPnl}" />
                </StackPanel>
            </StackPanel>
        </Border>

        <StackPanel Grid.Row="1" Orientation="Horizontal">
            <Button Content="Add" Margin="5" Height="30" Width="50" Command="{Binding PushButton}"/>
            <ToggleButton Content="&gt;&gt;" Margin="5" Height="30" Width="50">
                <ToggleButton.Triggers>
                    <EventTrigger RoutedEvent="ToggleButton.Unchecked">
                        <BeginStoryboard>
                            <Storyboard x:Name="HideStackPanel">
                                <DoubleAnimation Storyboard.TargetName="stkEasyLocatePanel" Storyboard.TargetProperty="Width" From="0" To="400" Duration="0:0:1.0">
                                    <DoubleAnimation.EasingFunction>
                                        <PowerEase EasingMode="EaseIn" />
                                    </DoubleAnimation.EasingFunction>
                                </DoubleAnimation>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content">
                                    <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="&gt;&gt;" />
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                    <EventTrigger RoutedEvent="ToggleButton.Checked">
                        <BeginStoryboard>
                            <Storyboard x:Name="ShowStackPanel">
                                <DoubleAnimation Storyboard.TargetName="stkEasyLocatePanel" Storyboard.TargetProperty="Width" From="400" To="0" Duration="0:0:1.0">
                                    <DoubleAnimation.EasingFunction>
                                        <PowerEase EasingMode="EaseIn" />
                                    </DoubleAnimation.EasingFunction>
                                </DoubleAnimation>
                                <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Content">
                                    <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="&lt;&lt;" />
                                </ObjectAnimationUsingKeyFrames>
                            </Storyboard>
                        </BeginStoryboard>
                    </EventTrigger>
                </ToggleButton.Triggers>
            </ToggleButton>
        </StackPanel>
    </Grid>
</UserControl>

MainViewModel.cs

using System.Collections.ObjectModel;
using System.Windows;
using Prism.Commands;
using Prism.Mvvm;

namespace ListViewSample
{
    public class ParameterItem
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public double Value { get; set; }

        public ParameterItem(int id, string name, double value)
        {
            Id = id;
            Name = name;
            Value = value;
        }
    }

    public class MainViewModel : BindableBase
    {
        int idx = 0;
        double vle = 123.45d;

        public ObservableCollection<ParameterItem> ParametersList { get; set; }

        private ParameterItem _selectedItem;
        public ParameterItem SelectedItem
        {
            get => _selectedItem;
            set
            { 
                SetProperty(ref _selectedItem, value, nameof(SelectedItem));
            }
        }

        public DelegateCommand PushButton { get; }
        public DelegateCommand PushButtonPnl { get; set; }

        public MainViewModel() 
        {
            ParametersList = new();

            PushButton = new DelegateCommand(() => 
            {
                Something();
            });

            Something();

            PushButtonPnl = new DelegateCommand(() =>
            {
                var txt = _selectedItem == null ? "NULL" : _selectedItem.Value.ToString();
                MessageBox.Show(txt);
            });
        }

        private void Something()
        {
            ParametersList.Add(new ParameterItem(idx++, $"Par{idx}", vle * idx));
        }
    }
}
c# wpf listview mvvm focus
1个回答
0
投票

当触发器无效时,它将恢复

ListBoxItem.IsSelected
属性的原始值,即
false

默认行为已经是正确的。焦点移开,但该项目仍保持选中状态。这种视觉状态称为“SelectedUnfocused”(请参阅ListBoxItem States)。

要保持视觉选定的反馈效果,您必须覆盖

ControlTemplate
以实现“SelectedUnfocused”状态动画(推荐)或实现新的选定触发器(因为这将删除默认触发器,因此也会删除“SelectedUnfocused”视觉状态).

例如:

<ListBox>
  <ListBox.ItemContainerStyle>
    <Style TargetType="ListBoxItem">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate TargetType="ListBoxItem">
            <Border Background="{TemplateBinding Background}"
                    BorderBrush="{TemplateBinding BorderBrush}"
                    BorderThickness="{TemplateBinding BorderThickness}"
                    Padding="{TemplateBinding Padding}">
              <ContentPresenter />
            </Border>

            <ControlTemplate.Triggers>
              <Trigger Property="IsMouseOver"
                       Value="True">
                <Setter Property="Background">
                  <Setter.Value>
                    <SolidColorBrush Color="{x:Static SystemColors.HighlightColor}"
                                     Opacity="0.1" />
                  </Setter.Value>
                </Setter>
                <Setter Property="BorderBrush">
                  <Setter.Value>
                    <SolidColorBrush Color="{x:Static SystemColors.HighlightColor}"
                                     Opacity="0.4" />
                  </Setter.Value>
                </Setter>
              </Trigger>
              <Trigger Property="IsSelected"
                       Value="True">
                <Setter Property="Background">
                  <Setter.Value>
                    <SolidColorBrush Color="{x:Static SystemColors.HighlightColor}"
                                     Opacity="0.2" />
                  </Setter.Value>
                </Setter>
                <Setter Property="BorderBrush">
                  <Setter.Value>
                    <SolidColorBrush Color="{x:Static SystemColors.HighlightColor}"
                                     Opacity="0.6" />
                  </Setter.Value>
                </Setter>
              </Trigger>
              <Trigger Property="IsEnabled"
                       Value="False">
                <Setter Property="Foreground"
                        Value="{x:Static SystemColors.GrayTextBrush}" />
              </Trigger>
            </ControlTemplate.Triggers>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </ListBox.ItemContainerStyle>
</ListBox>
© www.soinside.com 2019 - 2024. All rights reserved.