gpt4 book ai didi

c# - 在DataTrigger中未一致地调用Setter

转载 作者:行者123 更新时间:2023-12-03 10:43:39 24 4
gpt4 key购买 nike

注意:重写为MCVE

我有一个这样的用户界面,其意图是隐藏ListView(如果为空)或显示它,然后选择第一个项目(如果不为空)

<Window x:Class="BrokenSelection.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:BrokenSelection"
mc:Ignorable="d"
SizeToContent="WidthAndHeight"
Title="MainWindow">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<StackPanel>
<ListView x:Name="MyListView" ItemsSource="{Binding Items}">
<ListView.Style>
<Style TargetType="ListView">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="SelectedIndex" Value="0"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ListView.Style>
</ListView>
<Button Content="Set" Click="Button_Set"/>
<Button Content="Clear" Click="Button_Clear"/>
<Button Content="Step" Click="Button_Step"/>
</StackPanel>
</Window>

我有一个这样实现的虚拟机
class ViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

private List<string> items = new List<string>();
public List<string> Items
{
get
{
return items;
}

set
{
items = value;
PropertyChanged?.DynamicInvoke(this, new PropertyChangedEventArgs("Items"));
}
}
}

我有这样的代码背后
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}

private void Button_Set(object sender, RoutedEventArgs e)
{
var l = new List<string>();
l.Add("Item1");
l.Add("Item2");
l.Add("Item3");
l.Add("Item4");
l.Add("Item5");

var vm = DataContext as ViewModel;
vm.Items = l;
}

private void Button_Clear(object sender, RoutedEventArgs e)
{
var vm = DataContext as ViewModel;
vm.Items = new List<string>();
}

private void Button_Step(object sender, RoutedEventArgs e)
{
MyListView.SelectedIndex++;
}
}

我的问题是,只要单击“设置”,“清除”,“设置”,“清除”等, SetterSelectedIndex成功。

但是,如果我单击“设置”,“ 步骤”,“清除”,“设置”,则 SelectedIndex在第二个“设置”上最终为-1,而不是0。当列表消失并重新正确显示时,另一个 Setter会执行。为什么在触发器中手动更改 SelectedIndex会破坏它的 setter ?

最佳答案

这对我来说可以。请在下面查看我的Minimal, Complete, and Verifiable code example:

class ViewModel : INotifyPropertyChanged
{
private bool _hasItems;

public bool HasItems
{
get { return _hasItems; }
set { _UpdateValue(ref _hasItems, value); }
}

public ObservableCollection<string> Items { get; } = new ObservableCollection<string>();

public event PropertyChangedEventHandler PropertyChanged;

private void _UpdateValue<T>(ref T field, T newValue, [CallerMemberName] string propertyName = null)
{
if (!object.Equals(field, newValue))
{
field = newValue;
PropertyChanged?.DynamicInvoke(this, new PropertyChangedEventArgs(propertyName));

if (propertyName == nameof(HasItems))
{
if (HasItems)
{
Items.Add("test item");
}
else
{
Items.Clear();
}
}
}
}
}

<Window x:Class="TestSO39298712SelectedIndexSetter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:p="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:l="clr-namespace:TestSO39298712SelectedIndexSetter"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<l:ViewModel/>
</Window.DataContext>

<StackPanel>
<CheckBox IsChecked="{Binding HasItems}" Content="HasItems"/>
<TextBlock Text="{Binding SelectedIndex, ElementName=listBox1, StringFormat=SelectedIndex: {0}}"/>
<ListView x:Name="listBox1" ItemsSource="{Binding Items}">
<ListView.Style>
<p:Style TargetType="ListView">
<Setter Property="Visibility" Value="Collapsed"/>
<p:Style.Triggers>
<DataTrigger Binding="{Binding HasItems, RelativeSource={RelativeSource Self}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
<Setter Property="SelectedIndex" Value="0"/>
</DataTrigger>
</p:Style.Triggers>
</p:Style>
</ListView.Style>
</ListView>
</StackPanel>
</Window>

我直接将您提供的代码复制到此示例中。我所做的只是添加了足够多的其他代码,因此我有一个工作示例,可以演示 SelectedIndex属性是否确实发生了更改。

您可以查看上面的内容,以查看是否可以找到代码方面的不同之处。如果您仍然无法弄清楚自己犯了什么错误,请解决您的问题,使其包括上述的良好MCVE,但可以可靠地重现该问题。

关于c# - 在DataTrigger中未一致地调用Setter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39298712/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com