ListView控件跳或不缩水 [英] ListView jumps or does not shrink

查看:154
本文介绍了ListView控件跳或不缩水的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先必须与扩展不给后排空间崩溃的问题。
基于该边界这似乎是在ListView不缩水而非扩展器不缩小。
下面code固定萎缩的问题。
从<一个href="http://stackoverflow.com/questions/2955591/my-listview-or-listbox-control-size-doesnt-shrink-when-there-is-a-complex-data">ListBox控制不缩水
这失去了虚拟化,但我与OK,因为这是尽可能多的数据我需要显示。

First had the problem with collapse of Expander not giving back space.
Based on the borders it appears to be the ListView is not shrinking rather than the Expander not shrinking.
The following code fixed the shrinking problem.
From ListBox control does not shrink
This loses virtualization but I am OK with that as this is as much data as I need to display.

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

但随后的新问题。
如果你打开​​任何两个层面扩展,并尝试点击复选框会经常跳来跳去,有的时候跳这么多的点击错过的复选框。
一路滚动至底部,这样的复选框不可在底部(下面还有它的一些扩展器)。
然后点击它会跳,很可能甚至会错过的项目。
我需要尝试多次才能选中或取消选中的最后一行。
pretty的肯定,这是因为点击被处理两次和事物之间移动。

But then a new problem.
If you open up any two levels of Expander and try to click on the check box it will often jump around and some times jump so much that the click misses the check box.
Scroll all the way to the bottom so the check box is not at the bottom (there are some Expanders below it).
Then click and it will jump and most likely even miss the item.
I can take several attempts to check or uncheck the last row.
Pretty sure this is because of the click being processed twice and things moving between.

因此​​,如何解决这两个问题?
1.折叠收缩/回报空间?
2.检查框不跳?

So how to fix both problems?
1. Collapse shrink / give back space?
2. Check box not jumping?

通过调度试过刷新,UpdateLayout请(),InvalidateVisual(),和高度= Double.NaN。
在StackPanel中是没有问题的,因为我可以将其删除,并使用刚刚计算Exp1,仍然有问题。
双击时用的SelectedItem,我是能够食用的第二次点击修复,但该修复程序不会在这里工作之前也有类似的问题。 <一href="http://stackoverflow.com/questions/14755878/listbox-not-selecting-the-selected-item">MissClick
试过的TreeView但我不会显示在每个级别所以这是行不通的相同的信息。
但我愿意接受另一种方法。
两个层次结构,只需要在第二个层次复选框。

Tried refresh via dispatcher, UpdateLayout(), InvalidateVisual(), and Height = Double.NaN.
The StackPanel is not the problem as I can remove it and use just Exp1 and still have the problem.
Had a similar problem before on double click with SelectedItem that I was able to fix with eating the second click but that fix does not work here. MissClick
Tried TreeView but I am not displaying the same information at each level so it does not work.
But I am open to another approach.
Two level hierarchy and just need check boxes on the second level.

对不起了很多code,但是这是一个完整的程序来重现问题。
EXP1是相同的Exp2后并没有真正要重现该问题,但反映的情况下,有人提出一个替代的解决方案真正的程序。

Sorry for a lot of code but this is a complete program to reproduce the problem.
Exp1 is identical to Exp2 and not really necessary to reproduce the problem but that reflects the real program in case someone suggests an alternate solution.

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

我觉得有两个错误在这里。
控制不缩水,并点击得到处理两次。
我得到的收缩会增加开销,但仍为什么不是一个选项。

I think there are two bugs here.
Control not shrinking and a click getting processed twice.
I get shrink would add overhead but still why not an option.

推荐答案

它采取了与你的榜样打的好一点,但我最终意识到什么行为的根本原因,以及如何去寻找。

It took a good bit of playing with your example, but I eventually realised what the root cause of the behaviour was, and what to go looking for.

我觉得你经历引起你的复选框获得焦点的问题点击时,并养了 RequestBringIntoView 事件,这将从根本上导致的ScrollViewer 来踢包含您的复选框进入正确的地方的控制。机械师在这个答案解释:<一href="http://stackoverflow.com/questions/8384237/stop-wpf-scrollviewer-automatically-scrolling-to-perceived-content">Stop WPF的ScrollViewer自动滚动功能,感知内容。

I think you're experiencing an issue caused by your CheckBox gaining focus when clicked, and raising a RequestBringIntoView event, which will essentially cause the ScrollViewer to kick the control containing your CheckBox into the "correct" place. The mechanics are explained in this answer: Stop WPF ScrollViewer automatically scrolling to perceived content.

如果是滚动发生,而你点击一个复选框,它会从你的光标,然后才能unclick鼠标下移到了(你可以证明,通过举办出现问题时,按下鼠标,并随后将鼠标停留在该复选框的问题,并释放它)。

If that scroll happens whilst you're clicking on a CheckBox, it will move out from under your cursor before you can unclick the mouse (you can demonstrate that by holding the mouse down when the problem occurs, and subsequently moving your mouse over the CheckBox in question, and releasing it).

您可以创建一个简单的事件处理程序的<一个href="http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.requestbringintoview.aspx"相对=nofollow> RequestBringIntoView 事件和你的的DataTemplate 和副中使用它与复选框使用处理的属性,所以它不会传播任何进一步的(以下为我工作)。

You could create a simple event handler for the RequestBringIntoView event and use it with the CheckBox within your DataTemplate, and suppress the event using the Handled property, so it isn't propagated any further (the below worked for me).

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

复选框现在将不再正确使自己进入视野,如果它是稍微偏离屏幕,但它不会意外跳,你可以进一步自定义处理程序如果需要的话。

Your CheckBox would now no longer correctly bring itself into view if it was slightly off the screen, but it wouldn't jump unexpectedly, and you could customise the handler further if required.

这篇关于ListView控件跳或不缩水的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆