代码在这里 https://hastebin.com/uqumowediq.xml
请注意如何利用RadioButton来跟踪属性以检查其正确与否。
但是,基于ListBox构建的UserControl并非如此,
使用我的ListBox,我希望能够以EntryItemViewModel
的形式获得所选项目的数据,这很容易,我将更改Dependency属性的类型以将SelectedItem返回为EntryItemViewModel。
但是,我想像上面提供的gif一样滑出StackPanel,上面带有一个文本框,因此我可以将Title
属性绑定到该文本框的Text
属性。再次简单。
我的问题是.. 当我单击列表框中的项目时,我希望它将StackPanel滑到侧面。再次,就像上面的gif一样,当我选择另一个时,它会滑回,然后再次显示新数据,但这将是同一窗口。
我现在所拥有的就是这个。
我的UserControl
d:DesignHeight="300"
d:DesignWidth="300"
Height="535">
<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>
后跟UserControls
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
//Not sure what type this should be yet, I think this plays a big roll for this issue
public bool SelectedItem
{
get { return (bool)GetValue(MyPropertyProperty); }
set { SetValue(MyPropertyProperty, value); }
}
// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MyPropertyProperty =
DependencyProperty.Register("SelectedItem", typeof(bool), typeof(MyUserControl));
}
我在MainWindow中展示了UserControl,这就是我要存储将要滑出的StackPanel的地方,现在它只是一个立方体。
<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}" 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>
对于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));
}
}
最后但并非最不重要的AllEntriesViewModel.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));
}
}
DataContext设置为AllEntriesItemViewModel的新实例