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

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

У меня есть представление списка, которое может выбрать и отменить выбор элемента в нем, и я хочу, чтобы отменить его выбор по части элемента

Класс для выбора и отмены выбора элементов в представлении списка

public static class ListBoxSelectionBehavior
    {
        public static readonly DependencyProperty ClickSelectionProperty =
            DependencyProperty.RegisterAttached("ClickSelection",
                                                typeof(bool),
                                                typeof(ListBoxSelectionBehavior),
                                                new UIPropertyMetadata(false, OnClickSelectionChanged));

        public static bool GetClickSelection(DependencyObject obj)
        {
            return (bool)obj.GetValue(ClickSelectionProperty);
        }

        public static void SetClickSelection(DependencyObject obj, bool value)
        {
            obj.SetValue(ClickSelectionProperty, value);
        }

        private static void OnClickSelectionChanged(DependencyObject dpo, DependencyPropertyChangedEventArgs e)
        {
            ListView listBox = dpo as ListView;
            if (listBox != null)
            {
                if ((bool)e.NewValue == true)
                {
                    listBox.SelectionMode = SelectionMode.Multiple;
                    listBox.SelectionChanged += OnSelectionChanged;
                }
                else
                {
                    listBox.SelectionChanged -= OnSelectionChanged;
                }
            }
        }

        static void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (e.AddedItems.Count > 0)
            {
                ListView listBox = sender as ListView;
                var valid = e.AddedItems[0];
                foreach (var item in new ArrayList(listBox.SelectedItems))
                {
                    if (item != valid)
                    {
                        listBox.SelectedItems.Remove(item);
                    }
                }
            }
        }
    }

Класс для расширения панели обертки, чтобы добавить описание и все элементы

    public class WrapPaneEx : WrapPanel
    {
        protected override Size ArrangeOverride(Size finalSize)
        {
            var size = base.ArrangeOverride(finalSize);

            foreach (UIElement fe in this.Children)
            {
                var itemLocation = GetItemLocation(fe);
                if (itemLocation == null)
                {
                    itemLocation = new ItemLocation(this, fe);
                    SetItemLocation(fe, itemLocation);
                }
                itemLocation.OnLocationPropertyChanged();
            }
            return size;
        }

        public static ItemLocation GetItemLocation(DependencyObject obj)
        {
            return (ItemLocation)obj.GetValue(ItemLocationProperty);
        }

        public static void SetItemLocation(DependencyObject obj, ItemLocation value)
        {
            obj.SetValue(ItemLocationProperty, value);
        }

        public static readonly DependencyProperty ItemLocationProperty = DependencyProperty.RegisterAttached("ItemLocation", typeof(ItemLocation), typeof(WrapPaneEx), new PropertyMetadata(null));
    }

    public class ItemLocation : INotifyPropertyChanged
    {
        public ItemLocation(Panel panel, UIElement itemContainer)
        {
            this._Panel = panel;
            this._ItemContainer = itemContainer;
        }

        private UIElement _ItemContainer;
        private Panel _Panel;

        public Point? Location
        {
            get
            {
                if (_Location == null && _Panel != null && _ItemContainer != null)
                {
                    _Location = _ItemContainer.TranslatePoint(default(Point), _Panel);
                }
                return _Location;
            }
        }
        private Point? _Location;

        public Point? LocationN
        {
            get
            {
                if (_LocationN == null && _Location == null && _Panel != null && _ItemContainer != null)
                {
                    Point? np = Location;
                    if (np != null)
                    {
                        _LocationN = new Point(-np.Value.X, -np.Value.Y);
                    }
                }
                return _LocationN;
            }
        }
        private Point? _LocationN;

        public event PropertyChangedEventHandler PropertyChanged;

        internal void OnLocationPropertyChanged()
        {
            _Location = null;
            _LocationN = null;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Location)));
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(LocationN)));
        }
    }

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

<ScrollViewer  x:Name = "scollviewer" HorizontalAlignment = "Stretch" >
                        <ListView x:Name = "listview" Main:ListBoxSelectionBehavior.ClickSelection = "True" HorizontalAlignment = "Center" ItemsSource = "{Binding Items}" SelectedItem = "{Binding SelectedMovie}" PreviewMouseWheel = "List_PreviewMouseWheel">
                                <ListView.Resources>
                                    <ControlTemplate TargetType = "{x:Type ListViewItem}" x:Key = "withDetailTemplate">
                                        <Grid>
                                            <Grid.RowDefinitions>
                                                <RowDefinition Height = "Auto"/>
                                                <RowDefinition Height = "Auto"/>
                                            </Grid.RowDefinitions>
                                            <Border Grid.Row = "0" x:Name = "Bd" BorderBrush = "{TemplateBinding BorderBrush}" BorderThickness = "{TemplateBinding BorderThickness}" Background = "{TemplateBinding Background}" Padding = "0" SnapsToDevicePixels = "true">
                                                <Grid>
                                                    <local:MovieListItemControl/>
                                                    <Border Background = "White" Visibility = "Collapsed"
                                    Height = "2" Grid.RowSpan = "2" x:Name = "indicator"
                                    VerticalAlignment = "Bottom"/>
                                                </Grid>
                                            </Border>
                                            <!-- **************** -->
                                            <Canvas Grid.Row = "1" x:Name = "detailCanvas" 
                                                Width = "0" selec
                                                Height = "{Binding ElementName=detailGrid,Path=ActualHeight}"
                                                HorizontalAlignment = "Left" VerticalAlignment = "Top" Visibility = "Collapsed">
                                                <Grid x:Name = "detailGrid" Width = "{Binding RelativeSource = {RelativeSource Mode=FindAncestor,AncestorType = {x:Type ScrollViewer},AncestorLevel=2},Path=ActualWidth}"
                                                   Canvas.Left = "{Binding RelativeSource = {RelativeSource Mode=FindAncestor,AncestorType = {x:Type ListViewItem}},Path=(local:WrapPaneEx.ItemLocation).LocationN.X}">
                                                    <local:MovieDetailsControl/>
                                                </Grid>
                                            </Canvas>
                                            <!-- **************** -->
                                        </Grid>
                                        <ControlTemplate.Triggers>
                                            <Trigger Property = "IsSelected" Value = "true">
                                                <Setter Property = "Background" TargetName = "Bd" Value = "Black"/>
                                                <Setter Property = "Opacity" TargetName = "Bd" Value = "0.7"/>
                                                <Setter TargetName = "indicator" Property = "Visibility" Value = "Visible"/>
                                                <Setter TargetName = "detailCanvas" Property = "Visibility" Value = "Visible"/>

                                            </Trigger>
                                            <EventTrigger RoutedEvent = "Loaded">
                                                <EventTrigger.Actions>
                                                    <BeginStoryboard>
                                                        <Storyboard>
                                                            <DoubleAnimation Storyboard.TargetProperty = "Opacity" From = "0" To = "1" Duration = "0:0:1" />
                                                        </Storyboard>
                                                    </BeginStoryboard>
                                                </EventTrigger.Actions>
                                            </EventTrigger>
                                        </ControlTemplate.Triggers>
                                    </ControlTemplate>
                                </ListView.Resources>
                                <ListView.ItemContainerStyle>
                                    <Style TargetType = "{x:Type ListViewItem}">
                                        <Setter Property = "Template" Value = "{StaticResource withDetailTemplate}" />
                                    </Style>
                                </ListView.ItemContainerStyle>
                                <ListView.ItemsPanel>
                                    <ItemsPanelTemplate>
                                        <local:WrapPaneEx  HorizontalAlignment = "Center" Width = "{Binding RelativeSource = {RelativeSource Mode=FindAncestor,AncestorType = {x:Type ScrollViewer},AncestorLevel=2},Path=ActualWidth}"/>
                                    </ItemsPanelTemplate>
                                </ListView.ItemsPanel>
                            </ListView>
                    </ScrollViewer>

изображение для ожидаемой программы

Не могли бы вы привести пример кода того, что у вас есть прямо сейчас? Что вы пробовали и т.д.? Какие типы объектов находятся внутри listView?

vsarunov 22.05.2019 10:04

@vsarunov я добавляю туда код

Ghaith Abu Hakmeh 22.05.2019 10:21

Это одна и та же часть для выбора и отмены выбора? Например, флажок или переключатель? Который вы могли бы превратить во что-то похожее на что-то другое. Сделайте все остальные тесты на попадание видимыми ложными. И является фокусируемым ложным, поэтому вы не можете использовать стрелку или вкладку для него.

Andy 22.05.2019 10:24

это не работает для focussable, я пробовал

Ghaith Abu Hakmeh 22.05.2019 10:27

Вы пробовали вместо этого использовать IsHitTestVisible = "False"?

XAMlMAX 22.05.2019 11:54
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
71
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы хотите, чтобы некоторые элементы в вашем ListView были доступны только для чтения, вы должны использовать свойство IsHitTestVisible = "False" в ListViewIitem. Чтобы представить это в перспективе, можно создать стиль для ListViewIem, а затем использовать DataTrigger, чтобы включать и выключать его.

<Style TargetType = "ListViewItem">
    <Style.Triggers>
        <DataTrigger Binding = "Property" Value = "False">
            <Setter Property = "IsHitTestVisible" Value = "False"/>
        </DataTrigger>
    </Style.Triggers>
</Style>  

Поскольку это DependencyProperty, вы также можете напрямую привязать к этому свойству:

<Style TargetType = "ListViewItem">
    <Setter Property = "IsHitTestVisible" Value = "{Binding Property}"/>
</Style>

MSDN объяснение.
И вот краткое объяснение:

Gets or sets a value that declares whether this element can possibly be returned as a hit test result from some portion of its rendered content. This is a dependency property.

Другие вопросы по теме