c# - 当我单击 ListBoxItem 时,如何使 StackPanel 滑到一边

标签 c# .net wpf mvvm user-controls

所以我有一个带有我自己的 UserControl 的项目,它是围绕 ListBox 构建的。当我单击 ListBox 中的一个项目时,我想到达哪里,
我想要我的 StackPanel向右滑动。
当我点击另一个项目时,StackPanel应该滑回它开始的地方,然后再次滑出。

这可以使用 RadioButtons 来完成。但我不确定你是否可以以任何方式混合它们,因为 RadioButtons您可以使用 bool 值来跟踪是否选择了项目,因为 RadioButtonisChecked属性(property)。
到哪里去.. 如果 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 ofcourse 数据绑定(bind)它。

主窗口.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>

我的用户控件
<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));
        }
    }

编辑

我尝试添加一个转换器,但它仍然没有对我选择一个值使用react
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 但动画没有反应

最佳答案

你的原因<DataTrigger Binding="{Binding ElementName=UserControl, Path=SelectedItem.IsSelected}" Value="True">不起作用,因为您的 UserControl 没有属性名称 SelectedItem。它用于 UserControl 内的 ListBox。

您需要在 UserControl (AllEntriesListViewModel) 的 ViewModel 中创建一个属性“SelectedItem”并将 SelectedItem 绑定(bind)到该属性,然后如果您使用 DataContext.SelectedItem <DataTrigger Binding="{Binding ElementName=UserControl, Path=DataContext.SelectedItem.IsSelected}" Value="True">它将能够访问该属性。

编辑:

您还需要在 AllEntriesListViewModel 中再创建一个 bool 属性 IsSelected,并根据 SelectedItem 更改更改该属性。

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

并将数据触发器绑定(bind)到 DataContext.IsSelected。

关于c# - 当我单击 ListBoxItem 时,如何使 StackPanel 滑到一边,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52012776/

相关文章:

c# - C# 中的/= 运算符有什么作用?

c# - MonoTouch 和 LINQ - 由于对象的当前状态,操作无效

c# - 如何在 mvc5 中将文化设置为全局

c# - GZipStream 压缩问题(Lost Byte)

c# - 使用 WebSocketCollection 对象广播消息期间的错误处理

javascript - 如何在变量中获取 ClientID

wpf - 共享同一时间线的多个 Storyboard或动画?

wpf - Microsoft UI 自动化库与编码 UI 测试

c# - 绑定(bind) IIS 通配符子域

c# - 可移植类库中的 WPF MVVM 编程