代码之家  ›  专栏  ›  技术社区  ›  Nick Heiner

Silverlight4:用一点逻辑显示数据的模式?

  •  2
  • Nick Heiner  · 技术社区  · 14 年前

    我正在构建一个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 ,而不是崩溃如果 故事 是否为空?

    关于图像?我有一点逻辑性;在XAML中有什么方法可以自动做到这一点,还是在C中坚持这一点?

    1 回复  |  直到 14 年前
        1
  •  2
  •   Rob Fonseca-Ensor    14 年前

    看起来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)和视图(xaml)就可以做到这一点,但我希望您会发现,在可测试的、无砖墙的、视图特定的逻辑方面,视图模型给了您最大的能力…