Silverlight 4: Шаблон для отображения данных с небольшим количеством логики? - PullRequest
2 голосов
/ 31 октября 2010

Я создаю приложение wp7.

У меня есть UserControl, который отображает заголовок новостной статьи, тизер и изображение. Весь класс довольно короткий:

public partial class StoryControl : UserControl
{
    public Story Story { get; private set; }

    public StoryControl()
    {
        InitializeComponent();
    }

    internal StoryControl(Story story) : this()
    {
        this.Story = story;
        Teaser.Text = story.Teaser;
        Headline.Text = story.Title;

        if (story.ImageSrc == null)
        {
            Thumbnail.Visibility = Visibility.Collapsed;
        } else
        {
            Thumbnail.Source = new BitmapImage(story.ImageSrc);
        }
    }
}

И соответствующий XAML:

<Grid x:Name="LayoutRoot" Background="Transparent" Margin="0,0,0,20">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Image x:Name="Thumbnail" Grid.Column="0" Width="89" HorizontalAlignment="Left" VerticalAlignment="Top" />

    <!-- sometimes there's a hanging word in the headline that looks a bit awkward -->
    <TextBlock x:Name="Headline" Grid.Column="1" Grid.Row="0" Style="{StaticResource PhoneTextAccentStyle}" TextWrapping="Wrap" HorizontalAlignment="Left" FontSize="23.333" VerticalAlignment="Top" />
    <TextBlock x:Name="Teaser" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" HorizontalAlignment="Left" Style="{StaticResource PhoneTextSubtleStyle}"  TextWrapping="Wrap" VerticalAlignment="Top" Width="384"/>
</Grid>

Есть ли способ сделать это с меньшим количеством кода и большим количеством XAML? Какой-то способ использовать привязку для привязки текста для Headline и Teaser к свойствам Story, не прерывая работу, если Story равно нулю?

О насчет изображения? У меня есть немного логики там; Есть ли способ автоматически сделать это в XAML, или я застрял с этим в C #?

1 Ответ

2 голосов
/ 01 ноября 2010

Похоже, что ViewModel в порядке:

public class StoryViewModel
{
    readonly Story story;

    public StoryViewModel(Story story)
    {
        this.story = story;
    }

    public string Teaser { get { return story == null ? "" : story.Teaser; } }
    public string Title { get { return story == null ? "" : story.Title; } }
    public bool IsThumbnailVisible { get { return story != null && story.ImageSrc != null; } }
    public BitmapImage Thumbnail { get { return IsThumbnailVisible ? new BitmapImage(story.ImageSrc) : null; } }
}

Создание вашего кода красивым и простым:

public partial class StoryControl : UserControl
{
    public Story Story { get; private set; }

    public StoryControl()
    {
        InitializeComponent();

    }

    internal StoryControl(Story story)
        : this()
    {
        this.DataContext = new StoryViewModel(story);
    }
}

И ваш XAML становится набором привязок:

<Grid x:Name="LayoutRoot" Background="Transparent" Margin="0,0,0,20">
    <Grid.Resources>
        <BooleanToVisibilityConverter x:Key="booleanToVisiblityConverter"/>
    </Grid.Resources>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>

    <Image Visibility="{Binding IsThumbnailVisible, Converter={StaticResource booleanToVisiblityConverter}}" Source="{Binding Thumbnail}" Grid.Column="0" Width="89" HorizontalAlignment="Left" VerticalAlignment="Top" />

    <!-- sometimes there's a hanging word in the headline that looks a bit awkward -->
    <TextBlock Text="{Binding Title}" Grid.Column="1" Grid.Row="0" Style="{StaticResource PhoneTextAccentStyle}" TextWrapping="Wrap" HorizontalAlignment="Left" FontSize="23.333" VerticalAlignment="Top" />
    <TextBlock Text="{Binding Teaser}" Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" HorizontalAlignment="Left" Style="{StaticResource PhoneTextSubtleStyle}"  TextWrapping="Wrap" VerticalAlignment="Top" Width="384"/>

</Grid>

Хорошо, возможно, было бы возможно сделать это только с помощью модели (story) и view (xaml) с помощью fallbackvalues ​​и более сложных преобразователей, но я надеюсь, вы обнаружите, что viewmodels дают вам наибольшую мощность с точки зрения тестируемыхбез кирпичной стены, специфичная для вида логика ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...