有些事情看似簡單,在進行的過程中往往遇到大的麻煩;有些問題小之又小,但躲在角落裡竊笑的它能讓你嘔血數日。反正我不止一次遇到過這樣的情況。
日前我打算在産品中加入吊牌列印的功能,涉及到合格證的制作。大夥都有去商店裡買衣服的經曆,留意看吊牌的話會看到成分一欄裡分成好幾個類别,如面料、裡料、夾層等,每一類别又有好幾個物料占比資訊,如面料包含70%的棉和30%的xx纖維。如何能讓使用者較為友善地設定這些資訊呢?我原本打算采用自定義集合控件的方式,但是有些問題不好解決,部分難點問題記錄在随筆
WPF自定義集合控件概述與遇到的問題 中。于是我老老實實采用為ListBox建立Template的方式,期望達到如下效果:![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5yNyQWYlRTM2ETYhZzMwYTO5EWZ0MTMhlTZxYmNkNTYw0SMzYDNyADMz8CXyEjMxAjMvwVM0ADN3QzLcd2bsJ2Lc12bj5ycn9Gbi52YuAzcldWYtl2Lc9CX6MHc0RHaiojIsJye.png)
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>
代碼有點多,但結構還算清晰,編譯也能通過。但是,在頁面加載時抛出了NullReference異常,背景代碼設定的斷點都沒執行到。我任勞任怨地開始排查各段代碼,最後發現問題出在上述代碼的38行到47行之間,我不敢相信自己的眼睛,于是将異常代碼用另寫的一個測試按鈕<Button Content="Test" />代替,運作無問題。我接着開始重新開機VS、重新開機機子、拷貝代碼的艱苦旅程,問題依舊。最後我靈光乍現,取消注冊Click事件,運作無問題。此時我脆弱的大腦已經不堪思索,在嘗試用Command代替Event之前,我将希望投給了Bing(經過xx多年努力,Google已經成功被罷用了),發現有人遇到同我一樣的問題——
Binding to a converter and having a separate button's event assigned results in a nullreference exception?雖然提問并不十分準确,但描述的問題與我的類似,非常幸運的是,有高手解答了。在檢視了相關網址之後,我大緻心中有數,在此作一紀錄。
問題産生前提:
- You have a Microsoft .NET Framework 4.0-based Windows Presentation Foundation (WPF) application.
- In the application, there is one template that is nested inside another template.
- The inner (nested) template contains a control that specifies a style and an event. The style references a static resource.
解決方法:
- Set the style reference to a dynamic resource.
- Set the inner template as a resource for the outer template, and then remove the nest relationship.
更改後的代碼相當簡單,我就不貼出來了。
最後,我想把上面的整個GroupBox作為一個DataTemplate放到Resource中供頁面元素統一調用。
1 <DataTemplate x:Key="materielOutGPXTemplate">
2 <GroupBox ……
3 </DataTemplate>
然後同樣的異常又抛出來了。也許最外圍的DataTemplate也作為一層計算在内,此時第一個GroupBox的HeaderTemplate變成嵌套的内層了,又或許我的這個情況導緻了多層嵌套,事情會變得更加複雜?反正我按照前述的兩個方法都沒能解決該問題,隻好隻将GroupBox的其餘部分放入Resources中。世間事無完美,我隻能這麼安慰自己了。
轉載請注明本文出處:
http://www.cnblogs.com/newton/archive/2012/12/30/2839520.html