WPF:仿WP7短信列表

模仿WP7的短信列表效果,先来看下效果图:

Metro样式确实看着很舒服。下面来说下具体实现过程。

本来想写一个自定义控件,但是觉得没有用户控件来得方便,遂改成了用户控件,那首先新建一个用户控件。

起个名字:MetroListBoxItem。

前台的代码:

<Grid Margin="5 3 5 3" HorizontalAlignment="Left">
        <Grid.RowDefinitions>
            <RowDefinition Height="10*"/>
            <RowDefinition/>
            <RowDefinition Height="10*"/>
        </Grid.RowDefinitions>
        <Rectangle x:Name="rectTop" Grid.Row="0" Height="10" Width="10" HorizontalAlignment="Left">
            <Rectangle.RenderTransform>
                <TransformGroup>
                    <SkewTransform AngleY="45"/>
                    <TranslateTransform Y="5"/>
                </TransformGroup>
            </Rectangle.RenderTransform>
        </Rectangle>
        <StackPanel x:Name="panel" Grid.Row="1" Orientation="Vertical" Panel.ZIndex="1">
            <TextBlock MaxWidth="200" x:Name="txtContent" Margin="6 3 3 3" Foreground="White" FontSize="13" TextWrapping="Wrap"/>
            <TextBlock x:Name="txtTime" Margin="3 0 3 3" Foreground="WhiteSmoke" HorizontalAlignment="Right"/>
        </StackPanel>
        <Rectangle Visibility="Collapsed" x:Name="rectBottom" Grid.Row="2" Height="10" Width="10" HorizontalAlignment="Right">
            <Rectangle.RenderTransform>
                <TransformGroup>
                    <SkewTransform AngleY="45"/>
                    <TranslateTransform Y="-15"/>
                </TransformGroup>
            </Rectangle.RenderTransform>
        </Rectangle>
    </Grid>

 由于不像Iphone那样的短信列表,所以不需要很多的素材,实现起来很方便。

一个Grid,里面分为三行,上下两行分别放置两个气泡箭头,中间那层就放置内容。看下后台代码:

public bool IsLeft
        {
            get { return (bool)GetValue(IsLeftProperty); }
            set { SetValue(IsLeftProperty, value); }
        }

        // Using a DependencyProperty as the backing store for IsLeft.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty IsLeftProperty =
            DependencyProperty.Register("IsLeft", typeof(bool), typeof(MetroListBoxItem),
            new PropertyMetadata(true, (s, e) => OnChanged(s, e)));

        private static void OnChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
        {
            var item = s as MetroListBoxItem;

            if ((bool)e.NewValue == true)
            {
                item.rectTop.Visibility = Visibility.Visible;
                item.rectBottom.Visibility = Visibility.Collapsed;
            }
            else
            {
                item.rectTop.Visibility = Visibility.Collapsed;
                item.rectBottom.Visibility = Visibility.Visible;
                item.HorizontalAlignment = HorizontalAlignment.Right;
            }
        }

        public string Text
        {
            get { return txtContent.Text; }
            set
            {
                txtTime.Text = DateTime.Now.ToString("HH:mm:ss");
                txtContent.Text = value;
            }
        }

        public new Brush Background
        {
            set
            {
                rectTop.Fill = value;
                rectBottom.Fill = value;
                panel.Background = value;
            }
        }

先是声明了一个依赖属性:IsLeft,用来标识是在左边显示还是在右边。

然后是一个回调函数,当属性改变后做出相应的外观改变。也就是当显示为左边则把下层的气泡箭头隐藏掉,反之。

然后是两个属性,用来显示内容,和设置背景色。

接下来是主窗体前台代码:

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="348*" />
            <ColumnDefinition Width="155*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="280*" />
            <RowDefinition Height="35*" />
        </Grid.RowDefinitions>
        <ListBox Name="listBox" Grid.ColumnSpan="2">
            <ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                </Style>
            </ListBox.ItemContainerStyle>
        </ListBox>

        <Button Content="Left" Grid.Row="1" Height="23" Margin="3" Name="btnAddLeft" HorizontalAlignment="Left" Width="75" Grid.Column="1" Click="btnAddLeft_Click" />
        <Button Content="Right" Grid.Row="1" Height="23" Margin="3" Name="btnAddRight" HorizontalAlignment="Right" Width="75" Grid.Column="1" Click="btnAddRight_Click" />
        <TextBox Grid.Row="1" Height="23" Margin="5" Name="txtContent" Width="370" />
    </Grid>

 里面最主要的代码就是:

<ListBox.ItemContainerStyle>
                <Style TargetType="ListBoxItem">
                    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
                </Style>
            </ListBox.ItemContainerStyle>

 这个能调整布局。

然后是后台:

private void btnAddLeft_Click(object sender, RoutedEventArgs e)
        {
            items.Add(new MetroListBoxItem { Background = new SolidColorBrush { Color = Color.FromArgb(255, 30, 175, 45) }, Text = txtContent.Text, IsLeft = true });
            listBox.ItemsSource = items;
            ToBottom();
        }

        private void btnAddRight_Click(object sender, RoutedEventArgs e)
        {
            items.Add(new MetroListBoxItem { Background = new SolidColorBrush { Color = Color.FromArgb(255, 25, 130, 45) }, Text = txtContent.Text, IsLeft = false });
            listBox.ItemsSource = items;
            ToBottom();
        }
void ToBottom()
        {

            var sv = FindChildOfType<ScrollViewer>(listBox);

            sv.ScrollToEnd();
        }

两个按钮事件中动态的设置左右显示和背景色。

下面的方法是滚动到最下面,就像QQ消息框。

OK,还可以继续完善,比如为向下滚动添加动画效果...

Demo



 世界不会在意你的自尊,人们看的只是你的成就。在你没有成就以前,切勿过分强调自尊。——比尔·盖茨
原文地址:https://www.cnblogs.com/Walsh/p/2571452.html