1. 程式人生 > >通過字串生成Style並設定Style實現對ListBox裡面的呈現進行修改

通過字串生成Style並設定Style實現對ListBox裡面的呈現進行修改

最近專案中需要實現對ListBox呈現內容的外觀進行動態的修改,實現方式是通過修改DataTemplate裡面控制元件的Style,具體實現如下:

Xaml檔案:

<Window x:Class="StrStyle.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:StrStyle" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525">
<Window.Resources> <Style x:Key="itemBorder" TargetType="Border"> <Setter
Property="Background" Value="Aqua"/>
</Style> <DataTemplate x:Key="ItemTempalte"> <Border Style="{DynamicResource itemBorder}" Height="40" Width="100" BorderThickness="2"> <TextBlock Text="{Binding}"/> </Border> </DataTemplate
>
</Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition/> <RowDefinition/> </Grid.RowDefinitions> <ListBox x:Name="showList" ItemsSource="{Binding Items}" ItemTemplate="{StaticResource ItemTempalte}"></ListBox> <Grid Grid.Row="1"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition/> </Grid.RowDefinitions> <Button Height="40" Content="Apply" Click="Button_Click"/> <local:WpfPropertyGrid Grid.Row="1" x:Name="property"/> </Grid> </Grid> </Window>

裡面用到的WpfPropertyGrid是使用的[http://blog.csdn.net/wushang923/article/details/7352460]裡面給出的程式碼。

CS檔案如下:

namespace StrStyle
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            for (int index = 0; index < 100; index++)
            {
                Items.Add(index);
            }
            property.SelectedObject = Template;

            DataContext = this;
        }
        ItemBorder Template = new ItemBorder();

        public List<int> Items { get; set; } = new List<int>();

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            string TemplateStr = GetStyleStr(Template);
            var ss = XamlReader.Parse(TemplateStr); //將字串轉成對應的物件
            this.Resources["itemBorder"] = ss;//替換原來資源中的Style
        }

        string xmlns = " xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" ";
        //生成對應型別的Style的字串
        string GetStyleStr(object _obj)
        {
            Type type = _obj.GetType();
            string propertyStr = "";
            foreach (var item in type.GetProperties())
            {
                propertyStr += string.Format("<Setter Property=\"{0}\" Value=\"{1}\"/>\n",item.Name,item.GetValue(_obj,null));
            }

            string typeName = type.Name;
            switch(type.Name)
            {
                case "ItemBorder":
                    typeName = "Border";
                    break;
            }
            string typeStr = string.Format("TargetType=\"{0}\"", typeName);
            string str = "<Style  " + typeStr + xmlns +  "  >\n" +
                propertyStr + "</Style >";
            return str;
        }

        //定義一個對應的結構  保證屬性名相同
        public class ItemBorder
        {
            public int Height { get; set; } = 40;
            public Color BorderBrush { get; set; } = Colors.Red;
            public Color Background { get; set; } = Colors.Blue;
        }
    }
}

這裡使用的方式是先生成對應Style的字串,再將字串轉換成物件替換原來資源中對應的資源

具體效果如圖:
圖1
這裡寫圖片描述

圖2
這裡寫圖片描述