我实际上是为自定义ListView创建UserControl。 我想要实现的是与这篇文章相同的事情:Hide or Show stackpanel of ListViewItem with VisualStateManager。我已经实现了代码并且它可以工作,但现在我想让它更“通用”,所以我创建了一个用户控件。
我的控制分为两个网格。上部网格和折叠的隐藏网格。
我想使用我的用户控件:
<controls:ExpandableListView ItemsSource="{Binding ConnectedObjects}">
<controls:ExpandableListView.Header>
<TextBlock Text="Hello World!" />
</controls:ExpandableListView.Header>
<controls:ExpandableListView.ExpandedContent>
<Button Content="test 2" />
</controls:ExpandableListView.ExpandedContent>
</controls:ExpandableListView>
Header
属性是将放置在上部网格中的内容,ExpandedContent是放置在折叠网格中的内容。
在我的用户控件中,我有:
<ListView x:Name="LIST" SelectionChanged="LIST_SelectionChanged" ItemsSource="{Binding ItemsSource}">
<!-- Item container style -->
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<!-- Item template -->
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid x:Name="GRID_1" Grid.Row="0">
<ContentPresenter Content="{Binding Path=Header}" />
</Grid>
<Grid x:Name="GRID_2" Grid.Row="1" Visibility="Collapsed">
<ContentPresenter Content="{Binding Path=ExpandedContent}" />
</Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"></VisualState>
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="GRID_2.Visibility" Value="Visible"></Setter>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
用户控件背后有代码
public sealed partial class ExpandableListView : UserControl
{
private static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(
"ItemsSource",
typeof(IEnumerable),
typeof(ExpandableListView),
new PropertyMetadata(null));
public static readonly DependencyProperty HeaderContentProperty =
DependencyProperty.Register(
"Header",
typeof(Object),
typeof(ExpandableListView),
new PropertyMetadata(null));
public static readonly DependencyProperty ExpandedContentProperty =
DependencyProperty.Register(
"ExpandedContent",
typeof(Object),
typeof(ExpandableListView),
new PropertyMetadata(null));
public IEnumerable ItemsSource
{
get { return this.GetValue(ItemsSourceProperty) as IEnumerable; }
set { this.SetValue(ItemsSourceProperty, value); }
}
public Object Header
{
get { return (Object)this.GetValue(HeaderContentProperty); }
set { this.SetValue(HeaderContentProperty, value); }
}
public Object ExpandedContent
{
get { return (Object)this.GetValue(ExpandedContentProperty); }
set { this.SetValue(ExpandedContentProperty, value); }
}
public ExpandableListView()
{
this.InitializeComponent();
this.LIST.DataContext = this;
}
private void LIST_SelectionChanged(Object sender, SelectionChangedEventArgs e)
{
}
private void SetInEditMode()
{
VisualStateManager.GoToState(this, "Selected", true);
}
private void SetInViewMode()
{
VisualStateManager.GoToState(this, "Normal", true);
}
}
答案 0 :(得分:1)
我认为您需要添加内容属性以指定将哪个属性用作内容。例如:
[ContentProperty("ExpandedContent")]
public sealed partial class ExpandableListView : UserControl
{
...
public static readonly DependencyProperty ExpandedContentProperty =
DependencyProperty.Register(
"ExpandedContent",
typeof(Object),
typeof(ExpandableListView),
new PropertyMetadata(null));
...
public Object ExpandedContent
{
get { return (Object)this.GetValue(ExpandedContentProperty); }
set { this.SetValue(ExpandedContentProperty, value); }
}
...
}
此外,我更喜欢在依赖项属性声明中使用nemeof()
。它使代码更安全,重构和重命名:
public static readonly DependencyProperty ExpandedContentProperty =
DependencyProperty.Register(
nameof(ExpandedContent),
typeof(Object),
typeof(ExpandableListView),
new PropertyMetadata(null));
答案 1 :(得分:0)
<Grid x:Name="GRID_2" Grid.Row="1" Visibility="Collapsed">
<ContentPresenter Content="{Binding MyUsersContent }"/>
</Grid>
在您的控制CS文件中
public class YourControl{
public Object MyUsersContent
{
get { return (Object)GetValue(MyUsersContentProperty); }
set { SetValue(MyUsersContentProperty, value); }
}
public static readonly DependencyProperty MyUsersContentProperty =
DependencyProperty.Register("MyUsersContent",
typeof(Object), typeof(YoutControl), new PropertyMetadata());
}
这可能是最简单的方法。这就是我们需要看到你的代码的原因。因为它有助于您实现此功能。如果您在绑定时遇到问题,那么您可以在OnApplyTemplate函数中获取控件并手动将其泵入。
在你继续之前,我强烈建议你做这个教程。它将让您了解如何解决这个问题以及您将面临的许多其他问题。