[英]WPF Style Triggers in DataTemplate
我希望你能幫助我。 我在參考資料中得到了以下代碼:
<UserControl.Resources>
<BitmapImage x:Key="img_src_lock" UriSource="/EEBase;component/Images/Lock_24x32.png" />
<BitmapImage x:Key="img_src_unlock" UriSource="/EEBase;component/Images/Unlock_24x32.png" />
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource img_src_lock}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource img_src_unlock}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<!-- TypeComboTemplateCollapsed -->
<DataTemplate x:Key="TypeComboTemplateCollapsed">
<TextBlock
Text="{Binding Path=Text, Mode=OneWay}"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Margin="5,0,0,5"
/>
</DataTemplate>
<!-- TypeComboTemplateExpanded -->
<DataTemplate x:Key="TypeComboTemplateExpanded">
<TextBlock
Text="{Binding Path=Text, Mode=OneWay}"
VerticalAlignment="Center"
Margin="5,0,0,5"
/>
</DataTemplate>
<!-- EditCircleTemplate -->
<DataTemplate x:Key="EditCircleTemplate">
<!-- some content here, no ToggleButton -->
</DataTemplate>
<!-- EditRectangleTemplate -->
<DataTemplate x:Key="EditRectangleTemplate">
<!-- some other content here, including the ToggleButtons -->
<ToggleButton
IsChecked="{Binding Path=BaseLocked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
Margin="5"
/>
<ToggleButton
IsChecked="{Binding Path=HeightLocked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
Margin="5"
/>
</DataTemplate>
</UserControl.Resources>
在我看來,這一切都是正確的。
現在,問題是:當我執行以下操作時,會發生異常:
指定的元素已經是另一個元素的邏輯子級。 首先斷開連接。
1.加載控件,選擇的類型為CIRC
2.更改下拉列表以選擇RECT(正確顯示模板觸發器和切換按鈕)
3.將下拉菜單更改回CIRC
->現在發生異常。
4.如果我忽略異常,則不會加載模板“ EditCircleTemplate”,並且會顯示模型對象的常規ToString。
附加信息:
WPF最初有4種不同的類型,其中兩種帶有ToggleButtons(這就是我使用模板的原因)。 我把它們剪掉了,它們並沒有什么不同。 但是我發現使用所有4個模板時發現的是,切換到新模板時不會發生錯誤,而是使用切換按鈕卸載模板時不會發生錯誤。 這有點奇怪。 另外,如果我刪除了ToggleButtons的DataTriggers,那么一切都會像個符咒。
異常來自XAML解釋器,因此Stacktrace根本沒有用。
誰能給我一個提示我做錯了什么?
編輯:哎呀,我想我忘記了內容代碼:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="160"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<ComboBox
Margin="5"
Grid.Row="0"
Grid.Column="0"
ItemsSource="{Binding Path=PossibleTypes, Mode=OneTime}"
SelectedItem="{Binding Path=SelectedType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<ContentControl x:Name="content" Content="{Binding}" ContentTemplate="{StaticResource TypeComboTemplateExpanded}"/>
</StackPanel>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=ComboBoxItem}}" Value="{x:Null}">
<Setter TargetName="content" Property="ContentTemplate" Value="{StaticResource TypeComboTemplateCollapsed}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ContentControl
Grid.Column="0"
Grid.Row="1"
Grid.ColumnSpan="2"
Content="{Binding Mode=OneWay}">
<ContentControl.ContentTemplate>
<DataTemplate >
<ContentControl
Name="inputContent"
Content="{Binding Mode=OneWay}"
ContentTemplate="{x:Null}"
/>
<DataTemplate.Triggers>
<DataTrigger
Binding="{Binding Path=SelectedType.Type, Mode=OneWay}"
Value="CIRC">
<Setter
TargetName="inputContent"
Property="ContentTemplate"
Value="{StaticResource EditCircleTemplate}"
/>
</DataTrigger>
<DataTrigger
Binding="{Binding Path=SelectedType.Type, Mode=OneWay}"
Value="RECT">
<Setter
TargetName="inputContent"
Property="ContentTemplate"
Value="{StaticResource EditRectangleTemplate}"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ContentControl.ContentTemplate>
</ContentControl>
</Grid>
Edit2 /解決方案:
我只是找到了一種解決方法-它讓我不滿意:
與其將樣式放在UserControl.Resources中(對我而言這是更干凈直觀的解決方案),我必須分別在每個ToggleButton上使用觸發器設置樣式。
因此,刪除並向每個ToggleButton添加以下代碼即可達到目的:
<ToggleButton.Style>
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True" >
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource img_src_lock}" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Image Source="{StaticResource img_src_unlock}" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
仍然存在一個大問題: 為什么?
問題在於,如果您以一種樣式創建一個Image
,則只有一個實例,因此,一旦多個控件使用該樣式,就將對只能由一個控件擁有的一個實例進行爭奪。
最簡單的解決方案是將樣式放在資源中,並將x:Shared
設置為false,這樣,無論引用何處,都會使用樣式的副本。
為什么需要創建BitmapImages並將其設置為觸發器中內容圖像的源? 為什么不使用URI源直接訪問Images?
<Style TargetType="{x:Type ToggleButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="True">
<Setter Property="Content">
<Setter.Value>
<Image Source="/EEBase;component/Images/Lock_24x32.png" />
</Setter.Value>
</Setter>
</DataTrigger>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsChecked}" Value="False">
<Setter Property="Content">
<Setter.Value>
<Image Source="/EEBase;component/Images/Unlock_24x32.png" />
</Setter.Value>
</Setter>
</DataTrigger>
</Style.Triggers>
</Style>
讓我知道是否有幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.