其实也说不上算是教程了,只是把自己学习的代码拿出来分享一下,同时方便以后遇到类似问题的时候翻一下。
MSDN里如是说:
通常,如果有多个 DataTemplate 可用于同一类型的对象,并且您希望根据每个数据对象的属性提供自己的逻辑来选择要应用的 DataTemplate,则应创建 DataTemplateSelector。请注意,如果具有不同类型的对象,则可以对 DataTemplate 设置 DataType 属性。如果您执行了此操作,则无需创建 DataTemplateSelector。此外,如果对象类型相同但属性不同,也可以考虑使用 DataTrigger 或数据转换器。
通俗讲,就是根据不同的数据选择不同的模板。接下来,我用一个例子来讲述DataTemplateSelector和动态绑定的使用方法。
先看例子的UI:

图一

图二
一个Listbox三个button,listbox显示一个集合的数据,第一个button “change”点击后可以切换与listbox绑定的集合,第二个button给PersonCollection添加person实例,第三个button给AnimalCollection添加animal实例。
默认情况下listbox与PersonCollection绑定,程序启动后,点击Add person按钮会向PersonCollection添加一个person实例,listbox会显示该集合下数据,如果person类的gender属性为Female,则只显示name属性,并把边框改成蓝色。点击change后,listbox与AnimalCollection绑定,显示AnimalCollection数据,同样,Add animal添加animal实例,如果第二个属性不是4,则只显示animal的type属性,并修改边框为蓝色。
下面讲实现
第一步:建两个类,一个person,一个animal,这就是每个listbox item将来要显示的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//person类
    public class person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string _name;
        public string name
        {
            get
            {
                return _name;
            }
            set
            {
                if (value != _name)
                {
                    _name = value;
                    prochanged("name");
                }
            }
        }
        private string _gender;
        public string gender
        {
            get
            {
                return _gender;
            }
            set
            {
                if (value != _gender)
                {
                    _gender = value;
                    prochanged("gender");
                }
            }
        }
        private void prochanged(string info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

注意到这里,实现了INotifyPropertyChanged接口,需要引用命名空间System.ComponentModel.因为我希望这些属性改变的时候,listboxitem能自动更新,关于INotifyPropertyChanged接口,请看我另一篇日志wpf数据绑定binding与INotifyPropertyChanged
另一个类,animal与person基本类似,只是把person类里的属性:name和gender改成了type和legs。这里我就不贴代码了。
第二步:创建类DataContainer,包含两个集合,存储animal和person实例。代码:

1
2
3
4
5
6
7
8
9
10
    public class DataContainer
    {
        public  ObservableCollection<person> PersonCollection { get;set; }
        public  ObservableCollection<animal> AnimalCollection { get; set; }
        public DataContainer()
        {
            PersonCollection = new ObservableCollection<person>();
            AnimalCollection = new ObservableCollection<animal>();
        }
    }

我用了ObservableCollection,因为ObservableCollection已经实现了INotifyPropertyChanged接口,所以如果集合的项增删的时候UI会自动更新。(using System.Collections.ObjectModel;//ObservableCollection)
注意:假设最上面第一段代码person类里面,没有实现INotifyPropertyChanged接口,而这里仍然使用ObservableCollection来存储person列表的话,PersonCollection 里的项增加或删除时,UI的listbox也会相应的增删,但是当你想修改PersonCollection里某一个person实例的属性,比如gender由male变成female时,UI并不会更新,因为PersonCollection 并没变。所以,当你希望改变UI listbox item里某个person的属性时,person类就需要实现INotifyPropertyChanged接口。
第三步:定义数据模板。
当然首先在窗口里把需要的listbox和button放好。我的XAML代码如下:

1
2
3
4
5
6
7
    <Grid>
        <ListBox Margin="12,12,12,60" Name="listBox1"   HorizontalContentAlignment ="Stretch" ItemTemplateSelector="{StaticResource mytemplate_selector}">
        </ListBox>
        <Button Height="23" HorizontalAlignment="Left" Margin="12,0,0,12" Name="Change" VerticalAlignment="Bottom" Width="75" Click="Change_Click">Change</Button>
        <Button Height="23" Margin="120,0,109,12" Name="addperson" VerticalAlignment="Bottom" Click="addperson_Click">Add person</Button>
        <Button Height="23" HorizontalAlignment="Right" Margin="0,0,12,12" Name="addanimal" VerticalAlignment="Bottom" Width="75" Click="addanimal_Click">Add animal</Button>
    </Grid>

吃饭去了,回来再写……
继续,上面的XAML里的3个button没什么好说的,listbox里,最重要的一句是:ItemTemplateSelector=”{StaticResource mytemplate_selector}”,从字面意思理解,就是把一个叫做mytemplate_selector的静态资源,做为listbox的模板选择器。所以,接下来,定义我们需要资源,包括一个模板选择器和四个数据模板。模板选择器就是这里的mytemplate_selector,四个模板,person和animal各两个,通过模板选择器选择使用哪一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    <Window.Resources>
        <local:MyDataTemplateSelector x:Key="mytemplate_selector" />
        <DataTemplate x:Key ="person_template">
            <Border  Name="myborder" BorderBrush="Blue" Padding="5" Margin="2" BorderThickness="1">
            <StackPanel>
                <TextBlock  Text="{Binding Path=name}"></TextBlock >
                <TextBlock  Text="{Binding Path=gender}"></TextBlock >
            </StackPanel>
             </Border>
            <DataTemplate.Triggers>
                <DataTrigger  Value="Male" Binding="{Binding Path=gender}">           
                    <Setter TargetName="myborder" Property="BorderBrush" Value="Red" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
        <DataTemplate x:Key="male_template">
            <DataTemplate.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="FontSize" Value="20" />
                </Style>
            </DataTemplate.Resources>
            <Border  Name="myborder_male" BorderBrush="Blue" Padding="5" Margin="2" BorderThickness="1">
                <DockPanel>
                    <TextBlock Text="{Binding Path=name}"/>
                </DockPanel>
            </Border>
        </DataTemplate>
        <DataTemplate x:Key ="animal_template">
            <Border  Name="myborder" BorderBrush="Blue" Padding="5" Margin="2" BorderThickness="1">
                <StackPanel>
                    <TextBlock  Text="{Binding Path=type}"></TextBlock >
                    <TextBlock  Text="{Binding Path=legs}"></TextBlock >
                </StackPanel>
            </Border>
            <DataTemplate.Triggers>
                <DataTrigger  Value="4" Binding="{Binding Path=legs}">
                    <Setter TargetName="myborder" Property="BorderBrush" Value="Red" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
        <DataTemplate x:Key="fourlegs_template">
            <DataTemplate.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="FontSize" Value="20" />
                </Style>
            </DataTemplate.Resources>
            <Border  Name="myborder_male" BorderBrush="Blue" Padding="5" Margin="2" BorderThickness="1">
                <DockPanel>
                    <TextBlock Text="{Binding Path=type}"/>
                </DockPanel>
            </Border>
        </DataTemplate>
    </Window.Resources>

分析前面的XAML,在里面,我们共定义了五个资源,我简单分析一下前三个,后面两个跟第二个、第三个差不多,就不说多了。
第一个资源,定义了一个模板选择器,使用CS文件里的MyDataTemplateSelector类来选择模板。第二个资源,person_template, StackPanel里定义了普通的模板,显示person的name和gender,DataTrigger里定义了一个触发器,当gender为Male的时候,将item的border变成红色。这就是前面UI里不同的边框色的实现关键点。第三个资源male_template,定义了一个Male专用的模板,字体20号,只显示name。person_template模板里,边框颜色的变换通过DataTrigger就能实现,因为要修改的属性是在模板里存在的。但是当你想修改一些模板里不存的属性或者对于gender = male时使用另外完全不同的模板,那就要用到模板选择器了。下面分析前面提到的模板选择器,看着比较多,其实很简单,忍一忍认真点儿看完,你就能有更多收获。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//必须继承自DataTemplateSelector
 public class MyDataTemplateSelector:DataTemplateSelector
    {
        //覆盖SelectTemplate函数
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            Window win = Application.Current.MainWindow;
            //当前正在显示的是person类数据时:
            if (item != null && item is person)
            {               
                person p = item as person;
                //如果gender是male,将person_template做为现在的模板
                if (p.gender=="Male")
                {
                    return win.FindResource("person_template") as DataTemplate;
                }
                //否则就使用male_template
                else
                {
                    return win.FindResource("male_template") as DataTemplate;
                }
            }
            else if(item != null && item is animal)
            {
                animal a = item as animal;
                if (a.legs==4)
                {
                    return win.FindResource("animal_template") as DataTemplate;
                }
                else
                {
                    return win.FindResource("fourlegs_template") as DataTemplate;
                }
            }
            return null;
        }
    }

程序初初始化的时候:

1
2
3
4
5
6
7
8
9
10
11
        private bool isPersonDisplaying;
        private DataContainer dc;
        public Window1()
        {
            InitializeComponent();
            //表示当前正在显示的数据。默认显示person
            isPersonDisplaying = true;
            dc = new DataContainer();
            //指定数据源
            listBox1.ItemsSource = dc.PersonCollection;
        }

三个按钮的函数,change:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void Change_Click(object sender, RoutedEventArgs e)
        {
            changeBindingPath();
        }
        private void changeBindingPath()
        {
            if (isPersonDisplaying)
            {
                listBox1.ItemsSource = dc.AnimalCollection;
                isPersonDisplaying = false;
            }
            else
            {
                listBox1.ItemsSource = dc.PersonCollection;
                isPersonDisplaying = true;
            }
        }

这里实现不同数据源的切换,当数据源变换的时候,WPF会调用前面我们定义的模板选择器,选择正确的模板。
两个增加数据的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 private void addperson_Click(object sender, RoutedEventArgs e)
        {
            person p = new person();
            p.name = "PersonName" + System.DateTime.Now.Second.ToString();
            string gender = (System.DateTime.Now.Second%2)==1?"Male":"Female";
            p.gender = gender;
            dc.PersonCollection.Add(p);
        }

private void addanimal_Click(object sender, RoutedEventArgs e)
        {
            animal a = new animal();
            a.type = "AnimalType" + System.DateTime.Now.Second.ToString();
            a.legs = (System.DateTime.Now.Second % 2) == 1 ? 2 : 4;
            dc.AnimalCollection.Add(a);
        }

表达能力一般,水平一般,大家见谅。源代码我打了个包,点这里下载源码,编译环境:vs2008。

其实也说不上算是教程了,只是把自己学习的代码拿出来分享一下,同时方便以后遇到类似问题的时候翻一下。
MSDN里如是说:
通常,如果有多个 DataTemplate 可用于同一类型的对象,并且您希望根据每个数据对象的属性提供自己的逻辑来选择要应用的 DataTemplate,则应创建 DataTemplateSelector。请注意,如果具有不同类型的对象,则可以对 DataTemplate 设置 DataType 属性。如果您执行了此操作,则无需创建 DataTemplateSelector。此外,如果对象类型相同但属性不同,也可以考虑使用 DataTrigger 或数据转换器。
通俗讲,就是根据不同的数据选择不同的模板。接下来,我用一个例子来讲述DataTemplateSelector和动态绑定的使用方法。
先看例子的UI:

图一

图二
一个Listbox三个button,listbox显示一个集合的数据,第一个button “change”点击后可以切换与listbox绑定的集合,第二个button给PersonCollection添加person实例,第三个button给AnimalCollection添加animal实例。
默认情况下listbox与PersonCollection绑定,程序启动后,点击Add person按钮会向PersonCollection添加一个person实例,listbox会显示该集合下数据,如果person类的gender属性为Female,则只显示name属性,并把边框改成蓝色。点击change后,listbox与AnimalCollection绑定,显示AnimalCollection数据,同样,Add animal添加animal实例,如果第二个属性不是4,则只显示animal的type属性,并修改边框为蓝色。
下面讲实现
第一步:建两个类,一个person,一个animal,这就是每个listbox item将来要显示的数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//person类
    public class person : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string _name;
        public string name
        {
            get
            {
                return _name;
            }
            set
            {
                if (value != _name)
                {
                    _name = value;
                    prochanged("name");
                }
            }
        }
        private string _gender;
        public string gender
        {
            get
            {
                return _gender;
            }
            set
            {
                if (value != _gender)
                {
                    _gender = value;
                    prochanged("gender");
                }
            }
        }
        private void prochanged(string info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

注意到这里,实现了INotifyPropertyChanged接口,需要引用命名空间System.ComponentModel.因为我希望这些属性改变的时候,listboxitem能自动更新,关于INotifyPropertyChanged接口,请看我另一篇日志wpf数据绑定binding与INotifyPropertyChanged
另一个类,animal与person基本类似,只是把person类里的属性:name和gender改成了type和legs。这里我就不贴代码了。
第二步:创建类DataContainer,包含两个集合,存储animal和person实例。代码:

1
2
3
4
5
6
7
8
9
10
    public class DataContainer
    {
        public  ObservableCollection<person> PersonCollection { get;set; }
        public  ObservableCollection<animal> AnimalCollection { get; set; }
        public DataContainer()
        {
            PersonCollection = new ObservableCollection<person>();
            AnimalCollection = new ObservableCollection<animal>();
        }
    }

我用了ObservableCollection,因为ObservableCollection已经实现了INotifyPropertyChanged接口,所以如果集合的项增删的时候UI会自动更新。(using System.Collections.ObjectModel;//ObservableCollection)
注意:假设最上面第一段代码person类里面,没有实现INotifyPropertyChanged接口,而这里仍然使用ObservableCollection来存储person列表的话,PersonCollection 里的项增加或删除时,UI的listbox也会相应的增删,但是当你想修改PersonCollection里某一个person实例的属性,比如gender由male变成female时,UI并不会更新,因为PersonCollection 并没变。所以,当你希望改变UI listbox item里某个person的属性时,person类就需要实现INotifyPropertyChanged接口。
第三步:定义数据模板。
当然首先在窗口里把需要的listbox和button放好。我的XAML代码如下:

1
2
3
4
5
6
7
    <Grid>
        <ListBox Margin="12,12,12,60" Name="listBox1"   HorizontalContentAlignment ="Stretch" ItemTemplateSelector="{StaticResource mytemplate_selector}">
        </ListBox>
        <Button Height="23" HorizontalAlignment="Left" Margin="12,0,0,12" Name="Change" VerticalAlignment="Bottom" Width="75" Click="Change_Click">Change</Button>
        <Button Height="23" Margin="120,0,109,12" Name="addperson" VerticalAlignment="Bottom" Click="addperson_Click">Add person</Button>
        <Button Height="23" HorizontalAlignment="Right" Margin="0,0,12,12" Name="addanimal" VerticalAlignment="Bottom" Width="75" Click="addanimal_Click">Add animal</Button>
    </Grid>

吃饭去了,回来再写……
继续,上面的XAML里的3个button没什么好说的,listbox里,最重要的一句是:ItemTemplateSelector=”{StaticResource mytemplate_selector}”,从字面意思理解,就是把一个叫做mytemplate_selector的静态资源,做为listbox的模板选择器。所以,接下来,定义我们需要资源,包括一个模板选择器和四个数据模板。模板选择器就是这里的mytemplate_selector,四个模板,person和animal各两个,通过模板选择器选择使用哪一个。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
    <Window.Resources>
        <local:MyDataTemplateSelector x:Key="mytemplate_selector" />
        <DataTemplate x:Key ="person_template">
            <Border  Name="myborder" BorderBrush="Blue" Padding="5" Margin="2" BorderThickness="1">
            <StackPanel>
                <TextBlock  Text="{Binding Path=name}"></TextBlock >
                <TextBlock  Text="{Binding Path=gender}"></TextBlock >
            </StackPanel>
             </Border>
            <DataTemplate.Triggers>
                <DataTrigger  Value="Male" Binding="{Binding Path=gender}">           
                    <Setter TargetName="myborder" Property="BorderBrush" Value="Red" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
        <DataTemplate x:Key="male_template">
            <DataTemplate.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="FontSize" Value="20" />
                </Style>
            </DataTemplate.Resources>
            <Border  Name="myborder_male" BorderBrush="Blue" Padding="5" Margin="2" BorderThickness="1">
                <DockPanel>
                    <TextBlock Text="{Binding Path=name}"/>
                </DockPanel>
            </Border>
        </DataTemplate>
        <DataTemplate x:Key ="animal_template">
            <Border  Name="myborder" BorderBrush="Blue" Padding="5" Margin="2" BorderThickness="1">
                <StackPanel>
                    <TextBlock  Text="{Binding Path=type}"></TextBlock >
                    <TextBlock  Text="{Binding Path=legs}"></TextBlock >
                </StackPanel>
            </Border>
            <DataTemplate.Triggers>
                <DataTrigger  Value="4" Binding="{Binding Path=legs}">
                    <Setter TargetName="myborder" Property="BorderBrush" Value="Red" />
                </DataTrigger>
            </DataTemplate.Triggers>
        </DataTemplate>
        <DataTemplate x:Key="fourlegs_template">
            <DataTemplate.Resources>
                <Style TargetType="TextBlock">
                    <Setter Property="FontSize" Value="20" />
                </Style>
            </DataTemplate.Resources>
            <Border  Name="myborder_male" BorderBrush="Blue" Padding="5" Margin="2" BorderThickness="1">
                <DockPanel>
                    <TextBlock Text="{Binding Path=type}"/>
                </DockPanel>
            </Border>
        </DataTemplate>
    </Window.Resources>

分析前面的XAML,在里面,我们共定义了五个资源,我简单分析一下前三个,后面两个跟第二个、第三个差不多,就不说多了。
第一个资源,定义了一个模板选择器,使用CS文件里的MyDataTemplateSelector类来选择模板。第二个资源,person_template, StackPanel里定义了普通的模板,显示person的name和gender,DataTrigger里定义了一个触发器,当gender为Male的时候,将item的border变成红色。这就是前面UI里不同的边框色的实现关键点。第三个资源male_template,定义了一个Male专用的模板,字体20号,只显示name。person_template模板里,边框颜色的变换通过DataTrigger就能实现,因为要修改的属性是在模板里存在的。但是当你想修改一些模板里不存的属性或者对于gender = male时使用另外完全不同的模板,那就要用到模板选择器了。下面分析前面提到的模板选择器,看着比较多,其实很简单,忍一忍认真点儿看完,你就能有更多收获。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//必须继承自DataTemplateSelector
 public class MyDataTemplateSelector:DataTemplateSelector
    {
        //覆盖SelectTemplate函数
        public override DataTemplate SelectTemplate(object item, DependencyObject container)
        {
            Window win = Application.Current.MainWindow;
            //当前正在显示的是person类数据时:
            if (item != null && item is person)
            {               
                person p = item as person;
                //如果gender是male,将person_template做为现在的模板
                if (p.gender=="Male")
                {
                    return win.FindResource("person_template") as DataTemplate;
                }
                //否则就使用male_template
                else
                {
                    return win.FindResource("male_template") as DataTemplate;
                }
            }
            else if(item != null && item is animal)
            {
                animal a = item as animal;
                if (a.legs==4)
                {
                    return win.FindResource("animal_template") as DataTemplate;
                }
                else
                {
                    return win.FindResource("fourlegs_template") as DataTemplate;
                }
            }
            return null;
        }
    }

程序初初始化的时候:

1
2
3
4
5
6
7
8
9
10
11
        private bool isPersonDisplaying;
        private DataContainer dc;
        public Window1()
        {
            InitializeComponent();
            //表示当前正在显示的数据。默认显示person
            isPersonDisplaying = true;
            dc = new DataContainer();
            //指定数据源
            listBox1.ItemsSource = dc.PersonCollection;
        }

三个按钮的函数,change:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private void Change_Click(object sender, RoutedEventArgs e)
        {
            changeBindingPath();
        }
        private void changeBindingPath()
        {
            if (isPersonDisplaying)
            {
                listBox1.ItemsSource = dc.AnimalCollection;
                isPersonDisplaying = false;
            }
            else
            {
                listBox1.ItemsSource = dc.PersonCollection;
                isPersonDisplaying = true;
            }
        }

这里实现不同数据源的切换,当数据源变换的时候,WPF会调用前面我们定义的模板选择器,选择正确的模板。
两个增加数据的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 private void addperson_Click(object sender, RoutedEventArgs e)
        {
            person p = new person();
            p.name = "PersonName" + System.DateTime.Now.Second.ToString();
            string gender = (System.DateTime.Now.Second%2)==1?"Male":"Female";
            p.gender = gender;
            dc.PersonCollection.Add(p);
        }

private void addanimal_Click(object sender, RoutedEventArgs e)
        {
            animal a = new animal();
            a.type = "AnimalType" + System.DateTime.Now.Second.ToString();
            a.legs = (System.DateTime.Now.Second % 2) == 1 ? 2 : 4;
            dc.AnimalCollection.Add(a);
        }

 
 
表达能力一般,水平一般,大家见谅。源代码我打了个包,点这里下载源码,编译环境:vs2008。

wpf 模板选择器DataTemplateSelector及动态绑定使用教程的更多相关文章

  1. 【转】wpf 模板选择器DataTemplateSelector及动态绑定,DataTemplate.Triggers触发器的使用

    通常,如果有多个 DataTemplate 可用于同一类型的对象,并且您希望根据每个数据对象的属性提供自己的逻辑来选择要应用的 DataTemplate,则应创建 DataTemplateSelect ...

  2. wpf 模板选择器DataTemplateSelector及动态绑定,DataTemplate.Triggers触发器的使用

    通常,如果有多个 DataTemplate 可用于同一类型的对象,并且您希望根据每个数据对象的属性提供自己的逻辑来选择要应用的 DataTemplate,则应创建 DataTemplateSelect ...

  3. WPF/UWP 模板选择器 DataTemplateSelector

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  4. ItemsControl绑定的数据模板显示不同样式:模板选择器

    总所周知,wpf提供了数据模板,列表控件可以绑定数据实现批量显示同类型数据.不过同个数据模板显示不同的样式怎么办?这时我们可以用模板选择器. 首先我们可以将数据绑定到首先定义资源样式 <Data ...

  5. win10 uwp 列表模板选择器

    本文主要讲ListView等列表可以根据内容不同,使用不同模板的列表模板选择器,DataTemplateSelector. 如果在 UWP 需要定义某些列的显示和其他列不同,或者某些行的显示和其他行不 ...

  6. 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组

    [源码下载] 背水一战 Windows 10 (51) - 控件(集合类): ItemsControl - 项模板选择器, 数据分组 作者:webabcd 介绍背水一战 Windows 10 之 控件 ...

  7. 2019-11-29-win10-uwp-列表模板选择器

    原文:2019-11-29-win10-uwp-列表模板选择器 title author date CreateTime categories win10 uwp 列表模板选择器 lindexi 20 ...

  8. 2019-9-2-win10-uwp-列表模板选择器

    title author date CreateTime categories win10 uwp 列表模板选择器 lindexi 2019-09-02 12:57:38 +0800 2018-2-1 ...

  9. WPF快速入门系列(7)——深入解析WPF模板

    一.引言 模板从字面意思理解是“具有一定规格的样板".在现实生活中,砖块都是方方正正的,那是因为制作砖块的模板是方方正正的,如果我们使模板为圆形的话,则制作出来的砖块就是圆形的,此时我们并不 ...

随机推荐

  1. 【kindeditor】KindEditor获取多个textarea文本框的值并判断非空

    kindeditor官网:http://kindeditor.net/demo.php 如何获取多个KindEditor中textarea文本框的值,方式很多种(带有HTML标签). var intr ...

  2. postgresql-9.0.18-1-linux.run启动

    下载地址:http://www.enterprisedb.com/products-services-training/pgdownload选择合适版本 基本都是下一步就可以到设置密码时记住密码以后要 ...

  3. 【Windows API】OpenClipboard --- 剪切板(转)

    原文转自 http://www.cnblogs.com/wind-net/archive/2012/11/01/2749558.html 剪切板:系统维护的一个全局公共内存区域.每次只允许一个进程对其 ...

  4. 小程序 之使用HMACSHA1算法加密报文

    首先说说我们前端常用的加密技术, 我们常用的加密技术有:如MD5加密,base64加密 今天要说的是HMACSHA1加密技术 先介绍下什么是SHA1算法, 安全哈希算法(Secure Hash Alg ...

  5. SYN攻击SYN Attack

    SYN攻击SYN Attack   SYN Attack是一种DOS攻击方式.它利用的是TCP协议的漏洞,攻击目标,使其不在响应网络请求.在TCP协议中,需要三次握手,才能建立TCP连接.在握手过程中 ...

  6. IntelliJ IDEA常用统一设置2-Inspections检查设置(Linux/Mac/Windows)

    Inspections检查设置功能,能检查一些普通问题,比如代码风格等等.当然,这个虽然没有CheckStyle这些插件专业,但也是另一种选择. 官方参考:https://www.jetbrains. ...

  7. 邁向IT專家成功之路的三十則鐵律 鐵律二十七 IT人夢想之道-實踐

    有句話說:「人因夢想而偉大」.身為IT的您不知道夢想為何?是希望能夠環遊世界.開一間咖啡廳.買一部法拉利跑車.買一部重機.中大樂透頭彩.娶心目中的女神當老婆,還是只要明天還能活著就好了.無論您的夢想為 ...

  8. MySQL的1067错误

    1.打开my.ini文件,找到default-storage-engine=InnoDB这一行,把它改成default-storage-engine=MyISAM.*** my.ini必须为ansi格 ...

  9. mac mysql忘记密码解决办法

    http://www.jb51.net/article/87580.htm http://blog.csdn.net/soft2buy/article/details/50223373

  10. [zlib]_[0基础]_[使用Zlib完整解压zip内容]

    场景: 1. 解压文件一般用在下载了一个zip文件之后解压,或者分析某个文件须要解压的操作上. 2. 解压文件,特别是解压带目录的zip文件往往系统没有提供这类Win32 API,当然C#自带库能解压 ...