gpt4 book ai didi

.net - ListView跳转或者不收缩

转载 作者:行者123 更新时间:2023-12-03 02:53:28 25 4
gpt4 key购买 nike

首先遇到的问题是 Expander 崩溃而没有退还空间。
根据边框,似乎 ListView 没有缩小,而不是 Expander 没有缩小。
以下代码修复了缩小问题。
来自 ListBox control does not shrink
这会失去虚拟化,但我对此很满意,因为这就是我需要显示的数据量。

<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>

但是又出现了一个新问题。
如果您打开任意两级 Expander 并尝试单击复选框,它通常会跳来跳去,有时跳得太多,以至于单击错过了复选框。
一直滚动到底部,使复选框不在底部(下面有一些扩展器)。
然后点击,它会跳转,甚至很可能错过该项目。
我可以尝试多次尝试检查或取消检查最后一行。
很确定这是因为点击被处理了两次并且事物之间发生了移动。

那么如何解决这两个问题呢?
1. 折叠收缩/回馈空间?
2. 复选框不跳转?

尝试通过调度程序、UpdateLayout()、InvalidateVisual() 和 Height = Double.NaN 进行刷新。
StackPanel 不是问题,因为我可以将其删除并仅使用 Exp1,但仍然存在问题。
之前双击 SelectedItem 时也遇到过类似的问题,我可以通过第二次单击来修复该问题,但该修复在这里不起作用。 MissClick
尝试过 TreeView,但我没有在每个级别显示相同的信息,因此它不起作用。
但我愿意接受另一种方法。
两级层次结构,只需要第二级上的复选框。

抱歉,代码太多,但这是重现问题的完整程序。
Exp1 与 Exp2 相同,并不是重现问题所必需的,但它反射(reflect)了真实的程序,以防有人提出替代解决方案。

<Window x:Class="ListViewJump.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="165"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ScrollViewer Grid.Row="0" Grid.Column="0"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Visible">
<StackPanel>
<Expander IsExpanded="False" Header="Exp1" BorderThickness="2" BorderBrush="Green">
<ListView ItemsSource="{Binding Path=List1}"
HorizontalAlignment="Left" BorderThickness="2" BorderBrush="Orange">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate >
<DataTemplate>
<Expander Header="{Binding Path=DispName}">
<ListView ItemsSource="{Binding Path=Rows}"
HorizontalAlignment="Left" BorderThickness="2" BorderBrush="Purple">
<ListView.ItemTemplate >
<DataTemplate>
<CheckBox Width="125" IsChecked="{Binding Path=On}">
<TextBlock Text="{Binding Path=StrValue}" TextWrapping="Wrap"/>
</CheckBox>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
<Expander IsExpanded="False" Header="Exp2" BorderThickness="2" BorderBrush="Green">
<ListView ItemsSource="{Binding Path=List2}"
HorizontalAlignment="Left" BorderThickness="2" BorderBrush="Orange">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.ItemTemplate >
<DataTemplate>
<Expander Header="{Binding Path=DispName}">
<ListView ItemsSource="{Binding Path=Rows}"
HorizontalAlignment="Left" BorderThickness="2" BorderBrush="Purple">
<ListView.ItemTemplate >
<DataTemplate>
<CheckBox Width="125" IsChecked="{Binding Path=On}">
<TextBlock Text="{Binding Path=StrValue}" TextWrapping="Wrap"/>
</CheckBox>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Expander>
</StackPanel>
</ScrollViewer>
</Grid>
</Window>

namespace ListViewJump
{
public partial class MainWindow : Window
{
private List<ListItem> list1 = new List<ListItem>();
private List<ListItem> list2 = new List<ListItem>();
public MainWindow()
{
this.DataContext = this;
for (int i = 1; i < 10; i++)
{
List<ListItemRow> lr1 = new List<ListItemRow>();
List<ListItemRow> lr2 = new List<ListItemRow>();
for (int j = 1; j < 100; j++)
{
lr1.Add(new ListItemRow("Row Row Row Row Row Row" + j.ToString()));
lr2.Add(new ListItemRow("Rwo Rwo Rwo Rwo Rwo Rwo" + j.ToString()));
}
list1.Add(new ListItem("one " + i.ToString(), lr1));
list2.Add(new ListItem("two " + i.ToString(), lr2));
}
InitializeComponent();
}
public List<ListItem> List1 { get { return list1; } }
public List<ListItem> List2 { get { return list2; } }
}
public class ListItem
{
private string dispName;
private List<ListItemRow> rows;
public string DispName { get { return dispName; } }
public List<ListItemRow> Rows { get { return rows; } }
public ListItem(String DispName, List<ListItemRow> Rows) { dispName = DispName; rows = Rows; }
}
public class ListItemRow
{
private string strValue;
private bool on = false;
public string StrValue { get { return strValue; } }
public bool On
{
get { return on; }
set { on = value; }
}
public ListItemRow(String StrValue) { strValue = StrValue; }
}
}

我认为这里有两个错误。
控制不缩小并且点击被处理两次。
我得到收缩会增加开销,但仍然为什么不是一个选择。

最佳答案

花了很多时间研究你的例子,但我最终意识到这种行为的根本原因是什么,以及要寻找什么。

我认为您遇到的问题是由您的 CheckBox 在单击时获得焦点并引发 RequestBringIntoView 事件引起的,这实际上会导致 ScrollViewer 将包含 CheckBox 的控件踢到“正确”的位置。这个答案解释了机制:Stop WPF ScrollViewer automatically scrolling to perceived content .

如果在您单击 CheckBox 时发生滚动,则在您取消单击鼠标之前,它会从您的光标下方移出(您可以通过在出现问题时按住鼠标来演示)发生,然后将鼠标移到有问题的 CheckBox 上,然后释放它)。

您可以为 RequestBringIntoView 创建一个简单的事件处理程序事件并将其与 DataTemplate 中的 CheckBox 一起使用,并使用 Handled 属性抑制该事件,因此它不会进一步传播(以下内容对我有用)。

XAML:

<DataTemplate>
<CheckBox Width="125" IsChecked="{Binding Path=On}" RequestBringIntoView="RequestBringIntoViewSuppressor">
<TextBlock Text="{Binding Path=StrValue}" TextWrapping="Wrap"/>
</CheckBox>
</DataTemplate>

C#:

private void RequestBringIntoViewSuppressor(object sender, RequestBringIntoViewEventArgs e)
{
e.Handled = true;
}

如果您的 CheckBox 稍微偏离屏幕,现在将不再正确地将其自身显示在 View 中,但它不会意外跳转,并且您可以根据需要进一步自定义处理程序。

关于.net - ListView跳转或者不收缩,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20576934/

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