所以我有一个带有我自己的 UserControl 的项目,它是围绕 ListBox
构建的。当我单击 ListBox
中的一个项目时,我想到达哪里,
我想要我的 StackPanel
向右滑动。
当我点击另一个项目时,StackPanel
应该滑回它开始的地方,然后再次滑出。
这可以使用 RadioButtons
来完成。但我不确定你是否可以以任何方式混合它们,因为 RadioButtons
您可以使用 bool 值来跟踪是否选择了项目,因为 RadioButton
有isChecked
属性(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/