Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > WPF и Silverlight > ListView, проверить входит ли курсор мыши


Автор: Rohoss 17.10.2010, 17:35
Есть контрол ListView, который содержит три  элемента. Примерно выглядит всё так.
Код

            List<string> list = new List<string>();
            list.Add("item1");
            list.Add("item1");
            list.Add("item1");

            ListView lv = new ListView();
            lv.ItemsSource = list;

Как мне, при клике правой кнопки мыши на ListView узнать, находится ли курсор на каком-то из трёх элементов ListView или в пустой области (Той области ListView, где нет элементов)? Мне кажется решение должно содержатся в самом ListView, но не нашёл  smile 

Автор: WolfTheGrey 17.10.2010, 21:31
Пробовал ни как, Нужно обрабатывать два события: 
MouseLeftButtonDown="ListBox_MouseLeftButtonDown" - который обрабатывается событием MouseButtonEventArgs
 SelectionChanged="ListBox_SelectionChanged" а этот SelectionChangedEventArgs

Автор: Rohoss 18.10.2010, 18:47
Цитата(WolfTheGrey @  17.10.2010,  21:31 Найти цитируемый пост)
Пробовал ни как, Нужно обрабатывать два события: 
MouseLeftButtonDown="ListBox_MouseLeftButtonDown" - который обрабатывается событием MouseButtonEventArgs
 SelectionChanged="ListBox_SelectionChanged" а этот SelectionChangedEventArgs 

не совсем понял...

Автор: Kaerus 18.10.2010, 18:57
А зачем тебе это надо и ну что должно произойти (там событие вызваться или что). Потому как есть идеи, но надо цель уточнить.

Автор: Rohoss 18.10.2010, 23:37
Цитата(Kaerus @  18.10.2010,  18:57 Найти цитируемый пост)
А зачем тебе это надо и ну что должно произойти (там событие вызваться или что). Потому как есть идеи, но надо цель уточнить.

ну я хочу вызвать контекстное меню для списка одно, а для пустой области другое

Автор: WolfTheGrey 19.10.2010, 01:14
ёпть.
То что ты хочешь, сделать реально. Но пока моих знаний хватает на то, чтоб контекстменю прописывать в ручную.
вот что у меня получилось:
Код

<ListBox Width="100" Height="300" Canvas.Left="0" Canvas.Top="20">
                <ListBox.ContextMenu>
                    <ContextMenu BorderThickness="2" >
                        <MenuItem Header="file">
                            <MenuItem Header="open"/>
                            <MenuItem Header="sawe"/>
                        </MenuItem>                        
                    </ContextMenu>
                </ListBox.ContextMenu>                
                
                <ListBoxItem Content="a">
                    <ListBoxItem.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Cuit"/>
                            <MenuItem Header="Copu"/>
                            <MenuItem Header="Paste"/>
                        </ContextMenu>
                    </ListBoxItem.ContextMenu>
                </ListBoxItem>
                <ListBoxItem Content="b">
                    <ListBoxItem.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Cuit"/>
                            <MenuItem Header="Copu"/>
                            <MenuItem Header="Paste"/>
                        </ContextMenu>
                    </ListBoxItem.ContextMenu>
                </ListBoxItem>
                <ListBoxItem Content="c">
                    <ListBoxItem.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Cuit"/>
                            <MenuItem Header="Copu"/>
                            <MenuItem Header="Paste"/>
                        </ContextMenu>
                    </ListBoxItem.ContextMenu>
                </ListBoxItem>
                <ListBoxItem Content="d">
                    <ListBoxItem.ContextMenu>
                        <ContextMenu>
                            <MenuItem Header="Cuit"/>
                            <MenuItem Header="Copu"/>
                            <MenuItem Header="Paste"/>
                        </ContextMenu>
                    </ListBoxItem.ContextMenu>
                </ListBoxItem>
            </ListBox>

Можно сделать и так: (прописать сонекстменю в контейнее листбокса)
но в этом коде чего то не хватает, или что то не правельно.
Код

       <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Setter Property="Template">
                            <Setter.Value>
                                <ControlTemplate TargetType="ListBoxItem">
                                    <ContextMenu BorderThickness="2">
                                        <MenuItem Header="Cuit"/>
                                        <MenuItem Header="Copu"/>
                                        <MenuItem Header="Paste"/>
                                    </ContextMenu>
                                </ControlTemplate>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListBox.ItemContainerStyle>

Автор: WolfTheGrey 19.10.2010, 01:30
забей на то, что выше писал, все на много проще:
Код

<ListBox Width="100" Height="300" Canvas.Left="0" Canvas.Top="20">
                <ListBox.ContextMenu>
                    <ContextMenu BorderThickness="2" >
                        <MenuItem Header="file"/>
                            <MenuItem Header="open"/>
                            <MenuItem Header="sawe"/>
                                             
                    </ContextMenu>
                </ListBox.ContextMenu>

                <ListBox.ItemContainerStyle>
                    <Style TargetType="ListBoxItem">
                        <Setter Property="ContextMenu">
                            <Setter.Value> 
                                    <ContextMenu BorderThickness="2">
                                        <MenuItem Header="Cuit"/>
                                        <MenuItem Header="Copu"/>
                                        <MenuItem Header="Paste"/>
                                    </ContextMenu>
                            </Setter.Value>
                        </Setter>
                    </Style>
                </ListBox.ItemContainerStyle>

                <ListBoxItem>a</ListBoxItem>
                <ListBoxItem>b</ListBoxItem>
                <ListBoxItem>c</ListBoxItem>
                <ListBoxItem>d</ListBoxItem>
                <ListBoxItem>e</ListBoxItem>
            </ListBox>


Автор: Rohoss 19.10.2010, 14:04
WolfTheGrey, спасибо конечно, но тут дело в другом. Вызывается не контекстное меню WPF, а контекстное меню проводника. Есть класс, который принимает параметром элемент списка и точку(Point) а потом вызывает для них контекстное меню. Поэтому обрабатывать приходится клик правой кнопкой мыши…

Автор: WolfTheGrey 19.10.2010, 22:40
Немножко кода в студию пожалуйста.
от части интересует: 
  • контекстное меню проводника
  • Есть класс, который принимает параметром элемент списка и точку(Point) а потом вызывает для них контекстное меню
А зачем тебе параметр Поинт? чтоб определить где щелкнули (на пустом месте или по на каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListViewна каком-то из трёх элементов ListView). smile 

Автор: Kaerus 21.10.2010, 00:32
Как обычно в голову приходит использование WPF Behaviors
Код

class RightClickBehavior : Behavior<FrameworkElement>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.MouseRightButtonDown += AssociatedObject_MouseRightButtonDown;
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        AssociatedObject.MouseRightButtonDown -= AssociatedObject_MouseRightButtonDown;
    }

    void AssociatedObject_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
    {
        /// Тут можно прописать любой код обработки нажатия правой клавиши
        /// Для примера простой MessageBox
        MessageBox.Show(e.Source.ToString() + "\r\n" + e.GetPosition(e.Source as IInputElement).ToString());
    }
}

А вот применения в шаблоне (оптимальность решения не гарантирую, но работает)
Код

<ListBox ItemsSource="{Binding Items}" HorizontalContentAlignment="Stretch">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBlock Text="{Binding}" />
                <i:Interaction.Behaviors>
                    <local:RightClickBehavior/>
                </i:Interaction.Behaviors>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>

    <i:Interaction.Behaviors>
        <local:RightClickBehavior/>
    </i:Interaction.Behaviors>
</ListBox>

Автор: Rohoss 23.10.2010, 16:13
Kaerus, я так понимаю, использовать сборку содержащую класс Behavior<T> можно, установив Expression Blend? В библиотеках .NET 3.5 его нет?

Автор: Kaerus 23.10.2010, 16:44
Где то читал, что формально поведения не являются частью WPF, а появились в Exression Studio. Поэтому нужно будет поставить бленд и желательно 4 (если не ошибаюсь generic behaviors появились именно в 4.0 версии). 

P.S.
A Blend надо ставить однозначно. Лично я сейчас уже не представляю как можно работать с WPF без бленда

Автор: DenWPF 23.10.2010, 17:38
если я верно понял задачу, то при нажатии правой кнопки если это listitem то он выделиться, а значит у ListBox будет SelectedItem.

используй это.

только там вроде надо будет повесить событие и функцию
Код


        private void OnPreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e)
        {
            TreeViewItem treeViewItem = VisualUpwardSearch<TreeViewItem>(e.OriginalSource as DependencyObject) as TreeViewItem;

            if (treeViewItem != null)
            {
                treeViewItem.Focus();
                e.Handled = true;
            }
        }
        static DependencyObject VisualUpwardSearch<T>(DependencyObject source)
        {
            while (source != null && source.GetType() != typeof(T))
                source = VisualTreeHelper.GetParent(source);

            return source;
        }

Автор: Rohoss 23.10.2010, 17:48
если элементы будут выделены и щёлкнуть правой кнопкой в пустую область они и останутся выделенными.

Автор: DenWPF 23.10.2010, 19:31
может быть я уже не помню что этот код делал...аа вроде он наоборот что когда нажимаешь правой кнопкой на элементе что бы он выделлялся

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)