Очистить выделение одного ListBox, если мы выберем в другом ListBox - PullRequest
0 голосов
/ 08 мая 2020

У меня есть сценарий, в котором два списка должны отображаться в одном окне, но пользователь может выбрать только один из них и продолжить.

Допустим, listbox1 и listbox2, если пользователь выбирает элемент в listbox1 и снова выберите из listbox2, выбранный элемент в listbox1 должен быть удален.

Я должен добиться этого только через xaml, а не из codebehind. поэтому я попробовал следующее:

  <Grid.Resources>
            <Storyboard  x:Key="temp" >
                <Int32Animation Storyboard.TargetName="lstbox"   Storyboard.TargetProperty="(ListBox.SelectedIndex)" 
                                     To="-1" Duration="0:0:.2" />
            </Storyboard>
            <Storyboard  x:Key="temp1" >
                <Int32Animation Storyboard.TargetName="listBox1"   Storyboard.TargetProperty="(ListBox.SelectedIndex)" 
                                     To="-1" Duration="0:0:.2" />
            </Storyboard>
        </Grid.Resources>

Как указано выше, создал две раскадровки для установки selectedIndex в -1 и вызвал эту раскадровку, когда выбор изменил триггер события, как показано ниже:

 <ListBox Name="listBox1" HorizontalAlignment="Left"  Grid.Column="1">
            <ListBox.Triggers>
                <EventTrigger RoutedEvent="ListBox.SelectionChanged">
                    <BeginStoryboard Storyboard="{StaticResource temp}"/>
                </EventTrigger>
            </ListBox.Triggers>
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="Background" Value="AliceBlue" />
                    <Setter Property="BorderBrush" Value="BlanchedAlmond" />
                    <Setter Property="BorderThickness" Value="2" />
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Foreground" Value="Red" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBoxItem Content="Coffie"></ListBoxItem>
            <ListBoxItem Content="Tea"></ListBoxItem>
            <ListBoxItem Content="Orange Juice"></ListBoxItem>
            <ListBoxItem Content="Milk"></ListBoxItem>
            <ListBoxItem Content="Iced Tea"></ListBoxItem>
            <ListBoxItem Content="Mango Shake"></ListBoxItem>
        </ListBox>
  <ListBox Name="lstbox" ItemsSource="{Binding MyData}"  Grid.Column="1"  Grid.Row="1" SelectionChanged="lstbox_SelectionChanged">
            <ListBox.Triggers>
                <EventTrigger RoutedEvent="ListBox.SelectionChanged">
                    <BeginStoryboard Storyboard="{StaticResource temp1}"/>
                </EventTrigger>
            </ListBox.Triggers>
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="Background" Value="AliceBlue" />
                    <Setter Property="BorderBrush" Value="BlanchedAlmond" />
                    <Setter Property="BorderThickness" Value="2" />
                    <Style.Triggers>
                        <Trigger Property="IsSelected" Value="True">
                            <Setter Property="Foreground" Value="DarkViolet" />
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>

Через код позади, когда я установил для SelectedIndex значение -1, стили для selectedItem очищаются, но через раскадровку стили не очищаются.

Пожалуйста, расскажите другим способом или помогите мне заставить его работать. это только через xaml.

Спасибо,

Nagasree.

1 Ответ

0 голосов
/ 08 мая 2020

На основе вашего образца, если вы измените свои раскадровки таким образом, это будет работать:

        <Storyboard x:Key="temp">
            <ObjectAnimationUsingKeyFrames
                Storyboard.TargetName="lstbox"
                Storyboard.TargetProperty="SelectedItem">
                <ObjectAnimationUsingKeyFrames.KeyFrames>
                    <DiscreteObjectKeyFrame
                        KeyTime="0:0:0"
                        Value="null" />
                </ObjectAnimationUsingKeyFrames.KeyFrames>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>

        <Storyboard x:Key="temp1">
            <ObjectAnimationUsingKeyFrames
                Storyboard.TargetName="listBox1"
                Storyboard.TargetProperty="SelectedItem">
                <ObjectAnimationUsingKeyFrames.KeyFrames>
                    <DiscreteObjectKeyFrame
                        KeyTime="0:0:0"
                        Value="null" />
                </ObjectAnimationUsingKeyFrames.KeyFrames>
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>

Однако, как упоминалось комментаторами. Если вы используете MVVM и привязку данных к SelectedItem и т. Д. c., Это может не сработать.

Если ваш босс позволит вам использовать Behavior, вы можете сделать что-то вроде этого:

<ListBox
    Name="ListBox1"
    ItemsSource="{Binding MyData1}"
    SelectedItem="{Binding SelectedMyData1, Mode=TwoWay}">
    <i:Interaction.Behaviors>
        <local:ListBoxSingleSelectionBehavior TargetListBox="{Binding ElementName=ListBox2}" />
    </i:Interaction.Behaviors>
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Background" Value="AliceBlue" />
            <Setter Property="BorderBrush" Value="BlanchedAlmond" />
            <Setter Property="BorderThickness" Value="2" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Foreground" Value="Red" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
<ListBox
    Name="ListBox2"
    ItemsSource="{Binding MyData2}"
    SelectedItem="{Binding SelectedMyData2, Mode=TwoWay}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="Background" Value="AliceBlue" />
            <Setter Property="BorderBrush" Value="BlanchedAlmond" />
            <Setter Property="BorderThickness" Value="2" />
            <Style.Triggers>
                <Trigger Property="IsSelected" Value="True">
                    <Setter Property="Foreground" Value="DarkViolet" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

А вот поведение:

using System.Windows;
using System.Windows.Controls;
using Microsoft.Xaml.Behaviors;

namespace SO
{
    public class ListBoxSingleSelectionBehavior : Behavior<ListBox>
    {
        private bool isSelectionChanging;

        public ListBoxSingleSelectionBehavior()
        {
        }

        #region TargetListBox (DependencyProperty)
        /// <summary>
        /// Identifies the TargetListBox property.
        /// </summary>
        public static readonly DependencyProperty TargetListBoxProperty =
            DependencyProperty.Register(
                "TargetListBox",
                typeof(ListBox),
                typeof(ListBoxSingleSelectionBehavior),
                new PropertyMetadata(null, OnTargetListBoxChanged));

        /// <summary>
        /// Gets or sets the target ListBox to monitor.
        /// </summary>
        public ListBox TargetListBox
        {
            get => (ListBox)GetValue(TargetListBoxProperty);
            set => SetValue(TargetListBoxProperty, value);
        }

        private static void OnTargetListBoxChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var behavior = (ListBoxSingleSelectionBehavior) d;

            var oldTargetListBox = (ListBox) e.OldValue;
            var newTargetListBox = (ListBox) e.NewValue;

            behavior.OnTargetListBoxChanged(oldTargetListBox, newTargetListBox);
        }

        private void OnTargetListBoxChanged(ListBox oldTargetListBox, ListBox newTargetListBox)
        {
            if (oldTargetListBox != null)
            {
                oldTargetListBox.SelectionChanged -= OnTargetSelectionChanged;
            }

            if (newTargetListBox != null)
            {
                newTargetListBox.SelectionChanged += OnTargetSelectionChanged;
            }
        }
        #endregion

        protected override void OnAttached()
        {
            base.OnAttached();
            AssociatedObject.SelectionChanged += OnSourceSelectionChanged;
        }

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

            if (AssociatedObject != null)
            {
                AssociatedObject.SelectionChanged -= OnSourceSelectionChanged;
            }
        }

        private void OnSourceSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (isSelectionChanging) return;

            isSelectionChanging = true;

            if (TargetListBox != null)
            {
                TargetListBox.SelectedItem = null;
            }

            isSelectionChanging = false;
        }

        private void OnTargetSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (isSelectionChanging) return;

            isSelectionChanging = true;

            if (AssociatedObject != null)
            {
                AssociatedObject.SelectedItem = null;
            }

            isSelectionChanging = false;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...