莱布尼茨 发表于 2013-1-3 15:37:54

WPF嵌套模板引发的血案

<div id="cnblogs_post_body">有些事情看似简单,在进行的过程中往往遇到大的麻烦;有些问题小之又小,但躲在角落里窃笑的它能让你呕血数日。反正我不止一次遇到过这样的情况。
日前我打算在产品中加入吊牌打印的功能,涉及到合格证的制作。大伙都有去商店里买衣服的经历,留意看吊牌的话会看到成分一栏里分成好几个类别,如面料、里料、夹层等,每一类别又有好几个物料占比信息,如面料包含70%的棉和30%的xx纤维。如何能让用户较为方便地设置这些信息呢?我原本打算采用自定义集合控件的方式,但是有些问题不好解决,部分难点问题记录在随笔WPF自定义集合控件概述与遇到的问题中。于是我老老实实采用为ListBox新建Template的方式,期望达到如下效果:
http://images.cnitblog.com/blog/474041/201212/30024631-0a3d6f1e9a134ea996036aa1614ead27.png
毫无疑问,上述效果需要俩ListBox,一个呈现大类,一个呈现小类,还得为它们准备各自的DataTemplate,还需要俩GroupBox,它们各自的HeaderTemplate也要额外处理。我微微一笑,流利地敲出代码的第一版本:
<div class="cnblogs_code"> 1 <GroupBox DataContext="{Binding Composition,Mode=TwoWay,Converter={StaticResource compositionConverter}}" 2             RenderOptions.BitmapScalingMode="NearestNeighbor" Padding="3"> 3   <GroupBox.HeaderTemplate> 4         <DataTemplate> 5             <StackPanel Orientation="Horizontal"> 6               <TextBlock Text="成分" /> 7               <!--猜测由于没有给GroupBox.Header赋予Content,因此HeaderTemplate里的控件的DataContext为Null--> 8               <!--猜测正确,具体请看WPF GroupBox HeaderTemplate and DataBinding http://stackoverflow.com/questions/2425079/wpf-groupbox-headertemplate-and-databinding--> 9               <Button x:Name="PART_AddButton" Height="16" Click="PART_AddButton_Click">10                     <Button.Content>11                         <Image Source="pack://application:,,,/View.Extension;Component/Images/plus.png" />12                     </Button.Content>13               </Button>14               <Button x:Name="PART_DeleteButton" Height="16" Click="PART_DeleteButton_Click">15                     <Button.Content>16                         <Image Source="pack://application:,,,/View.Extension;Component/Images/minus.png" />17                     </Button.Content>18               </Button>19             </StackPanel>20         </DataTemplate>21   </GroupBox.HeaderTemplate>22   <ListBox x:Name="lbxMateriels" ItemsSource="{Binding}" BorderThickness="0" ScrollViewer.VerticalScrollBarVisibility="Hidden">23         <ListBox.ItemContainerStyle>24             <Style TargetType="ListBoxItem">25               <Setter Property="Margin" Value="2" />26               <Setter Property="Template">27                     <Setter.Value>28                         <ControlTemplate TargetType="ListBoxItem">                                                    29                           <GroupBox Header="{Binding}">30                                 <GroupBox.HeaderTemplate>31                                     <DataTemplate>32                                       <StackPanel Orientation="Horizontal">33                                             <ComboBox ItemsSource="{Binding MaterielKinds,Source={StaticResource context}}" 34                                                                   MinWidth="60"35                                                                   SelectedValue="{Binding KindName}"36                                                                   SelectedValuePath="Name"37                                                                   DisplayMemberPath="Name" />38                                             <Button Height="16" Click="btnAddPercent_Click">39                                                 <Button.Content>40                                                   <Image Source="pack://application:,,,/View.Extension;Component/Images/plus.png" />41                                                 </Button.Content>42                                             </Button>43                                             <Button Height="16" Click="btnDeletePercent_Click">44                                                 <Button.Content>45                                                   <Image Source="pack://application:,,,/View.Extension;Component/Images/minus.png" />46                                                 </Button.Content>47                                             </Button>48                                       </StackPanel>49                                     </DataTemplate>50                                 </GroupBox.HeaderTemplate>51                                 <ListBox x:Name="lbxMaterielPercents" ScrollViewer.VerticalScrollBarVisibility="Hidden"52                                           ItemsSource="{Binding MaterielPercents}" BorderThickness="0">53                                     <ListBox.ItemTemplate>54                                       <DataTemplate>55                                             <Grid Margin="0 3 0 0">56                                                 <Grid.ColumnDefinitions>57                                                   <ColumnDefinition Width="Auto" />58                                                   <ColumnDefinition Width="*" />59                                                 </Grid.ColumnDefinitions>60                                                 <NumericUpDown Value="{Binding Percent}" Minimum="0" Maximum="100" CustomUnit="%" />61                                                 <ComboBox ItemsSource="{Binding AvailableMateriels,Source={StaticResource context}}"62                                                                   SelectedValue="{Binding MaterielName}"63                                                                   SelectedValuePath="Name"64                                                                   DisplayMemberPath="Name"65                                                                   Grid.Column="1" MinWidth="60" Margin="5 0 0 0"/>66                                             </Grid>67                                       </DataTemplate>68                                     </ListBox.ItemTemplate>69                                 </ListBox>70                           </GroupBox>71                         </ControlTemplate>72                     </Setter.Value>73               </Setter>74             </Style>75         </ListBox.ItemContainerStyle>76   </ListBox>77 </GroupBox>
页: [1]
查看完整版本: WPF嵌套模板引发的血案