C# 在其他数据模板中重用UWP XAML数据模板
我不完全确定如何清楚地表达我想做的事情,所以如果有什么不清楚的地方,我会提前道歉 我正在用uwpc编写一个Twitter客户端。我需要做的一件事是控制Twitter API返回的tweet数组中每个tweet的数据模板。我遇到的问题是,如果我为每种tweet类型创建一个单独的数据模板,我最终会得到很多相同的代码。这是因为tweet可以是tweet类型文本、图像、视频、GIF、URL、retweet和retweet with quote的任意组合 有没有一种方法可以在不同的Tweet类型之间重用主Tweet模板,而不必为每个可能的组合复制相同的数据模板 对于retweet和quote tweet,tweet对象包含一个嵌套的第二个tweet对象,用于retweet或quote tweet,也称为retweet+文本,但我不知道如何以任何方式传递第二个tweet对象,以允许我重用现有模板 这是我现在拥有的数据模板的一个例子——到目前为止,我只做过推特和转发。RetweetTemplate几乎与TweetTemplate相同,只是@username retweeted文本在网格顶部多了一行,绑定指向Tweet.RetweetedStatus而不是Tweet 那么,有没有一种方法可以用更少的冗余代码来实现这一点?还是我一直在为每种可能的组合制作一个近乎重复的模板,以适应媒体和媒体转发的推文C# 在其他数据模板中重用UWP XAML数据模板,c#,twitter,uwp,datatemplate,uwp-xaml,C#,Twitter,Uwp,Datatemplate,Uwp Xaml,我不完全确定如何清楚地表达我想做的事情,所以如果有什么不清楚的地方,我会提前道歉 我正在用uwpc编写一个Twitter客户端。我需要做的一件事是控制Twitter API返回的tweet数组中每个tweet的数据模板。我遇到的问题是,如果我为每种tweet类型创建一个单独的数据模板,我最终会得到很多相同的代码。这是因为tweet可以是tweet类型文本、图像、视频、GIF、URL、retweet和retweet with quote的任意组合 有没有一种方法可以在不同的Tweet类型之间重用主
<DataTemplate x:Key="TweetTemplate">
<Grid MinHeight="150" Width="450" BorderBrush="{ThemeResource SystemControlDisabledListMediumBrush}" BorderThickness="1" Margin="-12 0" Padding="10 5">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal" Padding="5">
<TextBlock Text="{Binding Path=User.Name}" Margin="0 0 8 0" FontWeight="Bold" />
<TextBlock Text="{Binding Path=User.ScreenName, Converter={StaticResource GetHandle}}" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
<TextBlock Text="⦁" Margin="8 0" />
<TextBlock Text="{Binding CreationDate, Converter={StaticResource FormatDate}}" />
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<TextBlock Text="{Binding Text}" Padding="5" TextWrapping="WrapWholeWords" />
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.5*" MaxWidth="100"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button x:Name="cmdComment" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="1">
<Button x:Name="cmdRetweet" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="2">
<Button x:Name="cmdLike" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="3">
<Button x:Name="cmdMessage" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
</Grid>
</Grid>
</DataTemplate>
<DataTemplate x:Key="RetweetTemplate">
<Grid MinHeight="150" MinWidth="420">
<Grid.RowDefinitions>
<RowDefinition Height="28"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal" Padding="4 8 4 0">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="12"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
</Style>
</StackPanel.Resources>
<Border Height="28">
<TextBlock Height="24" FontFamily="{StaticResource FontAwesome}" xml:space="preserve"><Run Text=" "/></TextBlock>
</Border>
<TextBlock Text="{Binding Path=User.Name}" />
<TextBlock Text=" retweeted"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<StackPanel Orientation="Horizontal" Padding="5">
<TextBlock Text="{Binding Path=RetweetedStatus.User.Name}" Margin="0 0 8 0" FontWeight="Bold" />
<TextBlock Text="{Binding Path=RetweetedStatus.User.ScreenName, Converter={StaticResource GetHandle}}" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
<TextBlock Text="⦁" Margin="8 0" />
<TextBlock Text="{Binding Path=RetweetedStatus.CreationDate, Converter={StaticResource FormatDate}}" />
</StackPanel>
</Grid>
<Grid Grid.Row="2">
<TextBlock Text="{Binding RetweetedStatus.Text}" Padding="5" TextWrapping="WrapWholeWords" />
</Grid>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.5*" MaxWidth="100"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button x:Name="cmdComment" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="1">
<Button x:Name="cmdRetweet" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="2">
<Button x:Name="cmdLike" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="3">
<Button x:Name="cmdMessage" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
</Grid>
</Grid>
</DataTemplate>
<local:TweetTemplateSelector x:Key="TweetTemplateSelector"
TweetTemplate="{StaticResource TweetTemplate}"
RetweetTemplate="{StaticResource RetweetTemplate}">
</local:TweetTemplateSelector>
通常,您需要为不同的消息类型创建匹配数据模板。UWP有一个类,可以用来动态选择指定的数据模板。比如说, ListViewDataTemplateSelector.cs 用法 那么,有没有一种方法可以用更少的冗余代码来实现这一点?还是我一直在为每种可能的组合制作一个近乎重复的模板,以适应媒体和媒体转发的推文
<DataTemplate x:Key="TweetTemplate">
<Grid MinHeight="150" Width="450" BorderBrush="{ThemeResource SystemControlDisabledListMediumBrush}" BorderThickness="1" Margin="-12 0" Padding="10 5">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal" Padding="5">
<TextBlock Text="{Binding Path=User.Name}" Margin="0 0 8 0" FontWeight="Bold" />
<TextBlock Text="{Binding Path=User.ScreenName, Converter={StaticResource GetHandle}}" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
<TextBlock Text="⦁" Margin="8 0" />
<TextBlock Text="{Binding CreationDate, Converter={StaticResource FormatDate}}" />
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<TextBlock Text="{Binding Text}" Padding="5" TextWrapping="WrapWholeWords" />
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.5*" MaxWidth="100"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button x:Name="cmdComment" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="1">
<Button x:Name="cmdRetweet" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="2">
<Button x:Name="cmdLike" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="3">
<Button x:Name="cmdMessage" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
</Grid>
</Grid>
</DataTemplate>
<DataTemplate x:Key="RetweetTemplate">
<Grid MinHeight="150" MinWidth="420">
<Grid.RowDefinitions>
<RowDefinition Height="28"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal" Padding="4 8 4 0">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="12"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
</Style>
</StackPanel.Resources>
<Border Height="28">
<TextBlock Height="24" FontFamily="{StaticResource FontAwesome}" xml:space="preserve"><Run Text=" "/></TextBlock>
</Border>
<TextBlock Text="{Binding Path=User.Name}" />
<TextBlock Text=" retweeted"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<StackPanel Orientation="Horizontal" Padding="5">
<TextBlock Text="{Binding Path=RetweetedStatus.User.Name}" Margin="0 0 8 0" FontWeight="Bold" />
<TextBlock Text="{Binding Path=RetweetedStatus.User.ScreenName, Converter={StaticResource GetHandle}}" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
<TextBlock Text="⦁" Margin="8 0" />
<TextBlock Text="{Binding Path=RetweetedStatus.CreationDate, Converter={StaticResource FormatDate}}" />
</StackPanel>
</Grid>
<Grid Grid.Row="2">
<TextBlock Text="{Binding RetweetedStatus.Text}" Padding="5" TextWrapping="WrapWholeWords" />
</Grid>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.5*" MaxWidth="100"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button x:Name="cmdComment" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="1">
<Button x:Name="cmdRetweet" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="2">
<Button x:Name="cmdLike" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="3">
<Button x:Name="cmdMessage" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
</Grid>
</Grid>
</DataTemplate>
<local:TweetTemplateSelector x:Key="TweetTemplateSelector"
TweetTemplate="{StaticResource TweetTemplate}"
RetweetTemplate="{StaticResource RetweetTemplate}">
</local:TweetTemplateSelector>
我知道你想要更少的冗余代码,但是你写的冗余代码越少,你需要的行为控制就越多。这将增加代码的复杂性。虽然为每种消息类型创建数据模板是多余的,但代码很简单
有没有一种方法可以在不同的Tweet类型之间重用主Tweet模板,而不必为每个可能的组合复制相同的数据模板
不可以。你不能将一个模板建立在另一个模板上。DataTemplate必须始终定义为一个整体,即您不能只覆盖模板的一部分,而保留模板的其余部分。XAML不支持这一点
还是我一直在为每种可能的组合制作一个近乎重复的模板,以适应媒体和媒体转发的推文
<DataTemplate x:Key="TweetTemplate">
<Grid MinHeight="150" Width="450" BorderBrush="{ThemeResource SystemControlDisabledListMediumBrush}" BorderThickness="1" Margin="-12 0" Padding="10 5">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal" Padding="5">
<TextBlock Text="{Binding Path=User.Name}" Margin="0 0 8 0" FontWeight="Bold" />
<TextBlock Text="{Binding Path=User.ScreenName, Converter={StaticResource GetHandle}}" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
<TextBlock Text="⦁" Margin="8 0" />
<TextBlock Text="{Binding CreationDate, Converter={StaticResource FormatDate}}" />
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<TextBlock Text="{Binding Text}" Padding="5" TextWrapping="WrapWholeWords" />
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.5*" MaxWidth="100"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button x:Name="cmdComment" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="1">
<Button x:Name="cmdRetweet" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="2">
<Button x:Name="cmdLike" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="3">
<Button x:Name="cmdMessage" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
</Grid>
</Grid>
</DataTemplate>
<DataTemplate x:Key="RetweetTemplate">
<Grid MinHeight="150" MinWidth="420">
<Grid.RowDefinitions>
<RowDefinition Height="28"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<StackPanel Orientation="Horizontal" Padding="4 8 4 0">
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="FontSize" Value="12"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
</Style>
</StackPanel.Resources>
<Border Height="28">
<TextBlock Height="24" FontFamily="{StaticResource FontAwesome}" xml:space="preserve"><Run Text=" "/></TextBlock>
</Border>
<TextBlock Text="{Binding Path=User.Name}" />
<TextBlock Text=" retweeted"/>
</StackPanel>
</Grid>
<Grid Grid.Row="1">
<StackPanel Orientation="Horizontal" Padding="5">
<TextBlock Text="{Binding Path=RetweetedStatus.User.Name}" Margin="0 0 8 0" FontWeight="Bold" />
<TextBlock Text="{Binding Path=RetweetedStatus.User.ScreenName, Converter={StaticResource GetHandle}}" Foreground="{ThemeResource SystemControlPageTextBaseMediumBrush}" />
<TextBlock Text="⦁" Margin="8 0" />
<TextBlock Text="{Binding Path=RetweetedStatus.CreationDate, Converter={StaticResource FormatDate}}" />
</StackPanel>
</Grid>
<Grid Grid.Row="2">
<TextBlock Text="{Binding RetweetedStatus.Text}" Padding="5" TextWrapping="WrapWholeWords" />
</Grid>
<Grid Grid.Row="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2.5*" MaxWidth="100"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
<ColumnDefinition Width="2.5*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Button x:Name="cmdComment" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="1">
<Button x:Name="cmdRetweet" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="2">
<Button x:Name="cmdLike" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
<Grid Grid.Column="3">
<Button x:Name="cmdMessage" Content="" Style="{StaticResource MetaButtons}" />
</Grid>
</Grid>
</Grid>
</DataTemplate>
<local:TweetTemplateSelector x:Key="TweetTemplateSelector"
TweetTemplate="{StaticResource TweetTemplate}"
RetweetTemplate="{StaticResource RetweetTemplate}">
</local:TweetTemplateSelector>
是的,恐怕是这样。您可以考虑使用类来创建模板,以便能够尽可能地重用尽可能多的标记。然后使用ContentPresenters在顶级模板中显示每个零件将每个演示者的ContentTemplate设置为DataTemplate也可以有单个单片模板,但使用x:Load确保VisualTree中只有所需零件,但从我在Xbox One上创建一些大型应用程序时的测试来看,这仍然会带来意想不到的性能成本。@JohnnyWestlake-我想我以前尝试过这一点,但无法在我的ContentPresenter标记中使用数据绑定。你有一个例子吗?