Как сделать часть элемента списка выбираемой, а другую нельзя выбрать 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
3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
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.

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