Как сделать, чтобы моя StackPanel скользила в сторону, когда я щелкаю элемент ListBoxItem - PullRequest
0 голосов
/ 25 августа 2018

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

Это можно сделать с помощью RadioButtons, но я не уверен, что вы можете смешивать их каким-либо образом, потому что с RadioButtons вы можете отслеживать, выбран ли элемент с помощью bool, потому что RadioButton имеет isChecked свойство. Добравшись до того, где ... Если RadioButton установлен, он превращается в true, а затем Animation срабатывает на True, а когда вы нажимаете новый RadioButton, он превращается в false, потому что тот, который вы имели выбранное больше не выбрано. Но потом true снова при нажатии на новый. И false явно вызовет слайд в анимации.

Итак, я думаю, мне нужно проверить, выбран ли элемент в ListBox, так что, может быть, что-то вроде этого?

foreach(Item item in MyListBox.Items)        
    if(MyListBox.SelectedItems.Contains(item)
        MyObject.Value = true;
    else
        MyObject.Value = false;

Но используя XAML, конечно, с данными, связанными с ним.

MainWindow.xaml

<Grid>
        <Grid.Resources>
            <system:Double x:Key="SlideOffSet">50</system:Double>
            <Storyboard x:Key="SlideRight">
                <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                 From="0" To="{StaticResource SlideOffSet}"
                                 Duration="0:0:0.2" />
            </Storyboard>
            <Storyboard x:Key="SlideLeft">
                <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                                 From="{StaticResource SlideOffSet}" To="0"
                                 Duration="0:0:0.2" />
            </Storyboard>
        </Grid.Resources>

        <local:MyUserControl x:Name="UserControl"/>

        <StackPanel Width="100"
                    Height="100"
                    Background="Gray">

            <StackPanel.Style>
                <Style TargetType="StackPanel">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=UserControl, Path=SelectedItem.IsSelected}" Value="True">
                            <DataTrigger.EnterActions>
                                <BeginStoryboard Storyboard="{StaticResource SlideRight}" />
                            </DataTrigger.EnterActions>
                            <DataTrigger.ExitActions>
                                <BeginStoryboard Storyboard="{StaticResource SlideLeft}" />
                            </DataTrigger.ExitActions>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </StackPanel.Style>

            <StackPanel.RenderTransform>
                <TranslateTransform />
            </StackPanel.RenderTransform>

        </StackPanel>

    </Grid>

My UserControl

<Grid Background="LightGray">
        <ListBox SelectionMode="Single" 
                 ItemsSource="{Binding Items}"
                 SelectedItem="{Binding SelectedItem}"
                 x:Name="TheListBox">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border Grid.Column="2" Padding="0,0,8,0">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <!-- Selected Item -->
                                <ColumnDefinition Width="Auto"/>
                                <!-- Image Item -->
                                <ColumnDefinition Width="Auto"/>
                                <!-- Main content-->
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
                            <!-- Item image -->
                            <Border Grid.Column="1" Padding="8">
                                <Image Source="{Binding Image}"
                                       UseLayoutRounding="True"
                                       RenderOptions.BitmapScalingMode="Fant"
                                       Height="40"
                                       Width="40"/>
                            </Border>


                            <!-- Main Content -->
                            <Border Grid.Column="2" Padding="0,0,8,0">
                                <StackPanel VerticalAlignment="Center">
                                    <!-- Main Content -->
                                    <TextBlock Text="{Binding Title, FallbackValue=Title}"
                                               TextTrimming="CharacterEllipsis"
                                               FontWeight="Bold"/>

                                    <!-- Main Content -->
                                    <TextBlock Text="{Binding Username, FallbackValue=Username}"
                                               TextTrimming="CharacterEllipsis"/>
                                    <!-- Website URl -->
                                    <TextBlock Text="{Binding Password, FallbackValue=https://facebook.com}" Foreground="Gray"
                                               TextTrimming="CharacterEllipsis"/>
                                </StackPanel>
                            </Border>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>

            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <Border x:Name="Border"
                                        BorderBrush="Transparent"
                                        BorderThickness="5,0,0,0">
                                    <ContentPresenter Margin="0,0,0,0" />
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="True">
                                        <Setter TargetName="Border" Property="BorderBrush" Value="LightSkyBlue" />
                                    </Trigger>


                                    <Trigger Property="IsSelected" Value="True">
                                        <Trigger.EnterActions>
                                            <BeginStoryboard>
                                                <Storyboard>
                                                    <DoubleAnimation
                                                        Storyboard.TargetProperty="Opacity"
                                                        From="0.0" To="1.0" Duration="0:0:1"/>
                                                </Storyboard>
                                            </BeginStoryboard>
                                        </Trigger.EnterActions>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>

                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>
    </Grid>

EntryItemViewModel.cs

public class EntryItemViewModel : INotifyPropertyChanged
    {
        private string _title;

        public string Title
        {
            get { return _title; }
            set { _title = value; }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

AllEntriesListViewModel.cs

public class AllEntriesListViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<EntryItemViewModel> Items { get; set; } = new ObservableCollection<EntryItemViewModel>();

        public EntryItemViewModel EntryItemViewModel { get; set; } = new EntryItemViewModel();

        public AllEntriesListViewModel()
        {
            Items.Add(new EntryItemViewModel { Title = "Hello World" });
            Items.Add(new EntryItemViewModel { Title = "Hello World1" });
            Items.Add(new EntryItemViewModel { Title = "Hello World2" });
            Items.Add(new EntryItemViewModel { Title = "Hello World3" });
        }


        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

EDIT

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

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if ((EntryItemViewModel)value != null)
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return null;
        }

<DataTrigger Binding="{Binding ElementName=MyUserControl, Path=AllEntriesListViewModel.SelectedItem.IsSelected, Converter={StaticResource EntryModelConverter}}" Value="True">

Если я установил точку останова для свойства, он получит выбранную EntryViewModel, но анимация не реагирует

1 Ответ

0 голосов
/ 25 августа 2018

Причина, по которой ваш <DataTrigger Binding="{Binding ElementName=UserControl, Path=SelectedItem.IsSelected}" Value="True"> не работает, поскольку ваш UserControl не имеет имени свойства SelectedItem. Это для ListBox внутри UserControl.

Вам необходимо создать свойство «SelectedItem» в вашей ViewModel из UserControl (AllEntriesListViewModel) и связать SelectedItem с этим свойством, а затем, если вы используете DataContext.SelectedItem <DataTrigger Binding="{Binding ElementName=UserControl, Path=DataContext.SelectedItem.IsSelected}" Value="True">, оно сможет получить доступ к свойству.

Edit:

Вам также необходимо создать еще одно логическое свойство IsSelected в AllEntriesListViewModel и изменить это свойство на основе изменения SelectedItem.

    private EntryItemViewModel _selectedItem;
    public EntryItemViewModel SelectedItem
    {
        get { return _selectedItem; }
        set
        {
            if(_selectedItem != value)
            {
                _selectedItem = value;
                IsSelected = !IsSelected;
                OnPropertyChanged(nameof(SelectedItem));
            }                
        }
    }

и привязать триггер данных к DataContext.IsSelected.

...