我有一个UWP应用程序,在其页面中我显示了一个项目列表。这些项不是同一个类,但是,这些类之间有许多相同的属性。因此,我更喜欢使用一个UserControl,而不是使用多个UserControl并使用TemplateSelector。但数据不会像我预期的那样显示出来。
我在这里给你一个例子。
我有一个名为 Base 的课程:
public class Base
{
public int Id { get; set; }
public string Name { get; set; }
}
和2个派生自它的类:
public interface ILiker
{
int LikeCount { get; set; }
bool? IsLiked { get; set; }
}
public class Liker : Base, ILiker
{
public int LikeCount { get; set; }
public bool? IsLiked { get; set; }
}
public interface IFollower
{
int FollowCount { get; set; }
bool? IsFollowed { get; set; }
}
public class Follower : Base, IFollower
{
public int FollowCount { get; set; }
public bool? IsFollowed { get; set; }
}
我的列表项类型为 Liker 或关注者,因此我实现了另一个类来统一它们:
public class Unified
{
private Type _type;
public Unified(Follower item)
{
_type = item.GetType();
BaseInfo = (Base)item;
FollowerInfo = (IFollower)item;
}
public Unified(Liker item)
{
_type = item.GetType();
BaseInfo = (Base)item;
LikerInfo = (ILiker)item;
}
public Base BaseInfo { get; set; }
public ILiker LikerInfo { get; set; }
public IFollower FollowerInfo { get; set; }
public new Type GetType()
{
return _type;
}
}
有时我需要在一个列表项中的2个不同位置显示 Base 类,因为我创建了一个单独的 BaseTemplate :
BaseTemplate.xaml :
<UserControl ...>
<StackPanel VerticalAlignment="Top">
<TextBlock FontSize="15" Foreground="Black" Text="{x:Bind Data.Name}" />
<TextBlock FontSize="10" Foreground="Gray" Text="{x:Bind Data.Id}" Margin="5" />
</StackPanel>
</UserControl>
BaseTemplate.xaml.cs :
public sealed partial class BaseTemplate : UserControl
{
public Base Data
{
get { return (Base)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(Base), typeof(BaseTemplate), new PropertyMetadata(null));
public BaseTemplate()
{
this.InitializeComponent();
}
}
还为我的列表项创建了一个模板:
UnifiedTemplate.xaml :
<UserControl ...>
<Grid VerticalAlignment="Top" Padding="{x:Bind Padding}" BorderBrush="{x:Bind BorderBrush}" BorderThickness="{x:Bind BorderThickness}" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<local:BaseTemplate Data="{x:Bind Data.BaseInfo}" />
<Button
Grid.Row="0"
Grid.Column="1"
Content="{x:Bind Data.BaseInfo}">
<Button.ContentTemplate>
<DataTemplate>
<local:BaseTemplate Data="{Binding}" />
</DataTemplate>
</Button.ContentTemplate>
</Button>
<StackPanel Grid.Row="1" Grid.ColumnSpan="2" Background="SlateGray">
<RichTextBlock x:Name="LikeBlock" x:DeferLoadStrategy="Lazy">
<Paragraph>
<InlineUIContainer>
<TextBlock Text="Like Count: " />
</InlineUIContainer>
<Run Text="{x:Bind Data.LikerInfo.LikeCount}" />
<LineBreak />
<InlineUIContainer>
<ToggleButton Content="Like" Tapped="OnLikeTapped" IsChecked="{x:Bind Data.LikerInfo.IsLiked}" />
</InlineUIContainer>
</Paragraph>
</RichTextBlock>
<RichTextBlock x:Name="FollowBlock" x:DeferLoadStrategy="Lazy">
<Paragraph>
<InlineUIContainer>
<TextBlock Text="Follow Count: " />
</InlineUIContainer>
<Run Text="{x:Bind Data.FollowerInfo.FollowCount}" />
<LineBreak />
<InlineUIContainer>
<ToggleButton Content="Follow" Tapped="OnFollowTapped" IsChecked="{x:Bind Data.FollowerInfo.IsFollowed}" />
</InlineUIContainer>
</Paragraph>
</RichTextBlock>
</StackPanel>
</Grid>
</UserControl>
UnifiedTemplate.xaml.cs :
public sealed partial class UnifiedTemplate : UserControl
{
public Unified Data
{
get { return (Unified)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
// Using a DependencyProperty as the backing store for Data. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register("Data", typeof(Unified), typeof(UnifiedTemplate), new PropertyMetadata(null, OnChanged));
private static void OnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var that = d as UnifiedTemplate;
if (that == null || e.NewValue == null) return;
var data = (Unified) e.NewValue;
if (data.GetType() == typeof(Liker))
{
that.FindName(nameof(LikeBlock));
}
else
{
that.FindName(nameof(FollowBlock));
}
}
public UnifiedTemplate()
{
this.InitializeComponent();
}
private void OnLikeTapped(object sender, TappedRoutedEventArgs e) {...}
private void OnFollowTapped(object sender, TappedRoutedEventArgs e) {...}
}
当我运行应用程序时,基类类数据根本不会显示。我的做法有什么问题? 对于这个长期的问题,对不起,这是我能给出的最简单的例子。
修改:Here是一个非常类似的项目,可以重现问题。