滚动列表框时阻止选择

时间:2013-01-06 18:41:53

标签: c# wpf listbox touch wpf-4.5

我有一个将鼠标事件转换为触摸事件的应用程序,因此我可以使用惯性滚动和其他触摸功能。该代码位于所选答案中:

WPF: Is there a possibility to "route" ordinary mouse events to touch events in Windows 7

我对ListBox的问题是,当我轻弹滚动时,它会选择项目。通常,触摸设备在滚动时不会选择ListBox项。我在这里缺少什么?

这是我正在使用的xaml:

<Window x:Class="ScrollingTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="600" Width="525">
    <Grid>
        <ListBox x:Name="testListBox"               
                 VirtualizingPanel.ScrollUnit="Pixel" 
                 SelectionMode="Single">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border CornerRadius="3" Height="60" Width="480" Background="LightGray" Margin="1">
                        <Label Content="{Binding}"/>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>               
        </ListBox>
    </Grid>
</Window>

代码背后:

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

        MouseTouchDevice.RegisterEvents(this);

        for (int i = 0; i < 300; i++)
        {
            testListBox.Items.Add("test " + i.ToString());
        }
    }       
}

3 个答案:

答案 0 :(得分:0)

我发现这样做的唯一方法是使用DataTriggerListBoxItem Focusable属性设置为false。在我的情况下,当用户轻弹滚动时,我将属性IsScrolling设置为false,当kenitic运动停止时,我将其设置为false,这会在轻弹列表时停止选择行为

此解决方案可能无法在您的方案中运行,但这是一个有效的示例,因为您可以适应您的工作。

的Xaml:

<Window x:Class="WpfApplication13.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Name="UI">
    <Grid DataContext="{Binding ElementName=UI}">
        <ListBox Margin="0,32,0,0" ItemsSource="{Binding List}" ScrollViewer.ScrollChanged="List_ScrollChanged">
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding IsScrolling, ElementName=UI}" Value="True">
                            <Setter Property="IsHitTestVisible" Value="False"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Button Content="{Binding}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

代码:

public partial class MainWindow : Window, INotifyPropertyChanged
{

    private ObservableCollection<string> myVar = new ObservableCollection<string>();
    private DateTime _lastScroll;

    public MainWindow()
    {
        InitializeComponent();
        MouseTouchDevice.RegisterEvents(this);
        for (int i = 0; i < 1000; i++)
        {
            List.Add("StackOverflow " + i);
        }
    }

    public ObservableCollection<string> List
    {
        get { return myVar; }
        set { myVar = value; }
    }

    public bool IsScrolling
    {
        get { return !(DateTime.Now > _lastScroll.AddMilliseconds(100)); }
    }

    private void List_ScrollChanged(object sender, ScrollChangedEventArgs e)
    {
        _lastScroll = DateTime.Now;
        ThreadPool.QueueUserWorkItem((o) =>
        {
            Thread.Sleep(100);
            NotifyPropertyChanged("IsScrolling");
        });
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

答案 1 :(得分:0)

我认为这可以通过Adorners来实现。

MSDN样本 http://msdn.microsoft.com/en-us/library/ms771585(VS.85).aspx

装饰品非常简单;它可以在这里使用得很好。 请参阅以下链接,如果不首选叠加层,则可以将装饰图层背景设置为透明。

http://www.codeproject.com/Articles/57984/WPF-Loading-Wait-Adorner

答案 2 :(得分:0)

我知道这是一个老问题,但我已经确认了解决方案。 设置ScrollViewer.PanningMode属性可启用触摸滚动,从而阻止在MouseUp上进行选择。例如,设置PanningMode="VerticalOnly"以获得简单的滚动方案,你应该都很好。

希望我帮助过某人