Повторное использование шаблонов данных UWP XAML в других шаблонах данных - PullRequest
0 голосов
/ 01 июля 2018

Я не совсем уверен, как сформулировать то, что я пытаюсь сделать, поэтому заранее извиняюсь, если что-то неясно.

Я пишу клиент Twitter в UWP C #. Одна из вещей, которые мне нужно сделать, это управлять DataTemplate каждого твита в массиве твитов (как возвращено API Twitter). Проблема, с которой я сталкиваюсь, заключается в том, что в итоге я получу много идентичного кода, если сделаю отдельный DataTemplate для каждого типа твита. Это связано с тем, что твит может быть любым из типов твитов (текст, изображение, видео, GIF, URL, ретвит и ретвит с цитатой).

Вместо того, чтобы копировать одну и ту же DataTemplate для каждой возможной комбинации, можно ли повторно использовать основной шаблон Tweet для разных типов твитов?

Для ретвитов и твитов-цитат объект твита содержит вложенный второй объект твита (для ретвита или твита-цитаты, он же ретвит + текст), но я не знаю, как передать этот второй объект твита любым способом, который позволит мне повторно использовать мой существующий шаблон.

Вот пример моих DataTemplates, которые у меня есть сейчас - я пока только твиты и ретвиты. RetweetTemplate практически идентичен TweetTemplate, за исключением одной дополнительной строки в верхней части сетки для текста «ретвит @username», а привязки указывают на Tweet.RetweetedStatus вместо 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="&#x2981;" 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="&#xf075;" Style="{StaticResource MetaButtons}" />
            </Grid>
            <Grid Grid.Column="1">
                <Button x:Name="cmdRetweet" Content="&#xf079;" Style="{StaticResource MetaButtons}" />
            </Grid>
            <Grid Grid.Column="2">
                <Button x:Name="cmdLike" Content="&#xf004;" Style="{StaticResource MetaButtons}" />
            </Grid>
            <Grid Grid.Column="3">
                <Button x:Name="cmdMessage" Content="&#xf0e0;" 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="&#xf079;&#160;"/></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="&#x2981;" 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="&#xf075;" Style="{StaticResource MetaButtons}" />
            </Grid>
            <Grid Grid.Column="1">
                <Button x:Name="cmdRetweet" Content="&#xf079;" Style="{StaticResource MetaButtons}" />
            </Grid>
            <Grid Grid.Column="2">
                <Button x:Name="cmdLike" Content="&#xf004;" Style="{StaticResource MetaButtons}" />
            </Grid>
            <Grid Grid.Column="3">
                <Button x:Name="cmdMessage" Content="&#xf0e0;" Style="{StaticResource MetaButtons}" />
            </Grid>
        </Grid>
    </Grid>
</DataTemplate>

<local:TweetTemplateSelector x:Key="TweetTemplateSelector"
    TweetTemplate="{StaticResource TweetTemplate}"
    RetweetTemplate="{StaticResource RetweetTemplate}">
</local:TweetTemplateSelector>

Ответы [ 2 ]

0 голосов
/ 03 июля 2018

Вместо того, чтобы копировать одну и ту же DataTemplate для каждой возможной комбинации, есть ли способ повторно использовать основной шаблон твита между различными типами твитов?

Нет. Вы не можете основать шаблон на другом шаблоне. DataTemplate всегда должен быть определен как единое целое, т. Е. Вы не можете «переопределить» только некоторую часть шаблона, но оставьте остальную его часть. XAML не поддерживает это.

Или я застрял в создании почти дублированного шаблона для каждой возможной комбинации для размещения мультимедиа и ретвитов в твиттере с мультимедиа?

Да, я так боюсь. Можно подумать о создании шаблонов программно с использованием класса Xaml Reader , чтобы можно было повторно использовать как можно больше разметки.

0 голосов
/ 02 июля 2018

Как правило, вам нужно создать соответствие Datatemplate для другого типа сообщения. И UWP имеет класс DataTemplateSelector, который можно использовать для динамического выбора указанного Datatemplate. Например,

ListViewDataTemplateSelector.cs

public class ListViewDataTemplateSelector : DataTemplateSelector
{
    public DataTemplate MaleData { set; get; }
    public DataTemplate FemaleData { set; get; }

    protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
    {
        if (item is Male)
        {
            return MaleData;
        }
        return FemaleData;
    }
}

Использование

<Page.Resources>
    <DataTemplate x:Key="MaleData">
        <Grid>
           <Border>
               <Grid Margin="10,10,10,10">
                    <StackPanel>
                        <TextBlock Text="Name"></TextBlock>
                        <TextBlock Text="{Binding Path=Name}"></TextBlock>
                        <TextBlock Text="Height"></TextBlock>
                        <TextBlock Text="{Binding Path=Stature}"></TextBlock>
                    </StackPanel>
                </Grid>
           </Border>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="FemaleData">
        <Grid>
            <Border>
                <Grid Margin="10,10,10,10">
                    <StackPanel>
                        <TextBlock Text="Name"></TextBlock>
                        <TextBlock Text="{Binding Path=Name}"></TextBlock>
                        <TextBlock Text="Age"></TextBlock>
                        <TextBlock Text="{Binding Path=Year}"></TextBlock>
                    </StackPanel>
                </Grid>
            </Border>
        </Grid>
    </DataTemplate>
    <local:ListViewDataTemplateSelector x:Key="Selector" FemaleData="{StaticResource FemaleData}"
                                        MaleData="{StaticResource MaleData}"></local:ListViewDataTemplateSelector>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <ListView ItemsSource="{x:Bind View.HumanWorld}"
              ItemTemplateSelector="{StaticResource Selector}"></ListView>
    <TextBlock Text="http://blog.csdn.net/lindexi_gd" VerticalAlignment="Bottom"></TextBlock>
</Grid>

Так есть ли способ сделать это с меньшим количеством избыточного кода? Или я застрял в создании почти дублированного шаблона для каждой возможной комбинации для размещения мультимедиа и ретвитов в твиттере с мультимедиа?

Я знаю, что вы хотите меньше избыточного кода, но чем меньше избыточного кода вы пишете, тем больше необходим поведенческий контроль. Это увеличит сложность вашего кода. Хотя избыточно создавать Datatemplates для каждого типа сообщений, но код прост.

...