我想顯示一個列表框,其中的項目在選中時將顯示一個按鈕,該按鈕對所選數據項目執行特定操作。爲此,我使用兩個數據模板,一個是NormalTemplate(它沒有按鈕),另一個是SelectedTemplate(它有一個按鈕,其Tag屬性綁定到數據,用於按鈕單擊事件處理程序)。選擇Listbox中的項目時,我想分配SelectedTemplate。列表框中選定項目和普通項目的不同項目模板項目
爲此,我使用了具有VisualStateManager的自定義ControlTemplate,該VisualStateManager基於VisualState選擇適當的模板(即,選擇了& Unselected)。這個解決方案的問題是我每次需要使用不同的DataTemplates時都要創建一個新的ControlTemplate。我試圖找到一個解決方案,在其中指定正常的&所選項目的模板,並使用通用代碼根據視覺狀態更改數據模板。
下面是我的,未被選定&所選項目的DataTemplate:
<DataTemplate x:Key="NormalItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Margin="8,0,0,3" VerticalAlignment="Center">
<TextBlock Text="{Binding Name}" FontWeight="Bold" FontFamily="Arial" FontSize="14"/>
<TextBlock Text="{Binding Description}" />
</StackPanel>
</Grid>
</Border>
</DataTemplate>
<DataTemplate x:Key="SelectedItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="65"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Margin="8,0,0,3">
<TextBlock Text="{Binding Name}" FontWeight="Bold" FontFamily="Arial" FontSize="14"/>
<TextBlock Text="{Binding Description}" />
</StackPanel>
<Border Grid.Column="2" Grid.RowSpan="2" VerticalAlignment="Stretch">
<Button Content="Process" Tag={Binding} OnClick="Process_Clicked" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</Grid>
</Border>
</DataTemplate>
下面是定義自定義的控件模板,它使用VisualStateManager來顯示或隱藏相應的ContentPresenters它的ContentTemplate被分配到NormalItemTemplate & SelectedItemTemplate風格
<Style TargetType="ListBoxItem" x:Key="ActiveGamesItemContainerStyle">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Grid Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedContentPresenter" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="UnSelectedContentPresenter" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SelectedContentPresenter" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="UnSelectedContentPresenter" Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Collapsed</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter
x:Name="SelectedContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{StaticResource NormalItemTemplate}"
HorizontalAlignment="Stretch"
Margin="{TemplateBinding Padding}"
Visibility="Collapsed"/>
<ContentPresenter
x:Name="UnSelectedContentPresenter"
Content="{TemplateBinding Content}"
ContentTemplate="{StaticResource SelectedItemTemplate}"
HorizontalAlignment="Stretch"
Margin="{TemplateBinding Padding}"
Visibility="Visible"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
此解決方案的問題是:
對於每個需要使用不同DataTemplates的新ListBoxItem,我需要使用與上面相同的ControlTemplate創建樣式,但只需更改ContentPresenter的ContentTemplate。因此,很多重複的代碼/ XAML。
因爲我正在使用SelectedItemTemplate中的按鈕,所以我需要在定義Click事件處理程序的相同UserControl類中定義樣式。如果UserControl使用多個ListBox,則會爲每個ListBoxes聲明一個巨大的Style定義。
我試圖解決這個問題,使用附加的屬性,但它不工作。至於,我無法得到選定的ListBoxItem(而是我得到的綁定數據)。這個想法是讓ListBoxItem獲得它的ContentPresenter並將它的ContentTemplate設置爲SelectedItemTemplate。
有沒有更好的方法來做到這一點?
感謝&問候, 蘇尼爾
你怎麼會在Windows Phone的做到這一點(沒有Datatriggers) –