我遇到了一个问题,需要一点时间。我需要在我的Windows phone 8应用程序的多个页面上添加列表框,在每个页面上,ListBoxItem的正常/选定背景是不同的(10-12页)。一个解决方案是我为每个ListBoxItem为我的样式表中的每个页面硬编码颜色代码创建不同的样式(我不想要)。所以我扩展了ListBoxItem类,并为ListboxItem的正常和选定项目背景添加了2个依赖项属性。所以我可以在每个xaml页面上设置这些属性,而不必为每个页面创建不同的样式。 这是我的扩展控件
public class CustomListboxItem : ListBoxItem
{
public static readonly DependencyProperty NormalBackgroundProperty =
DependencyProperty.Register("NormalBackground", typeof(SolidColorBrush), typeof(CustomListboxItem), new PropertyMetadata(null));
public static readonly DependencyProperty SelectedBackgroundProperty =
DependencyProperty.Register("SelectedBackground", typeof(SolidColorBrush), typeof(CustomListboxItem), new PropertyMetadata(null));
public SolidColorBrush NormalBackground
{
get { return (SolidColorBrush)GetValue(NormalBackgroundProperty); }
set { base.SetValue(NormalBackgroundProperty, value); }
}
public SolidColorBrush SelectedBackground
{
get { return (SolidColorBrush)GetValue(SelectedBackgroundProperty); }
set { base.SetValue(SelectedBackgroundProperty, value); }
}
}
以下是如何使用它(CyclesList只是字符串列表):
<ListBox Grid.Row="1" ItemsSource="{Binding CyclesList}" ItemContainerStyle="{StaticResource FilterListBoxItemStyle}" >
<ListBox.ItemTemplate>
<DataTemplate>
<controls:CustomListboxItem NormalBackground="Transparent" Content="{Binding}" SelectedBackground="Red"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
以下是我申请使其成为通用的风格。
<Style x:Key="FilterListBoxItemStyle" TargetType="controls:CustomListboxItem">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="LayoutRoot" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" HorizontalAlignment="{TemplateBinding HorizontalAlignment}" VerticalAlignment="{TemplateBinding VerticalAlignment}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver"/>
<VisualState x:Name="Disabled"/>
</VisualStateGroup>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="Unselected"/>
<VisualState x:Name="Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="ContentContainer">
<DiscreteObjectKeyFrame KeyTime="0" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedBackground}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentControl x:Name="ContentContainer" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
Background="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=NormalBackground}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但是我的应用程序在这里抛出异常(完整堆栈跟踪):
{System.Windows.Markup.XamlParseException:[Line:0 Position:0] ---&gt; System.Windows.Markup.XamlParseException:[Line:0 Position:0] ---&gt; System.Windows.Markup.XamlParseException:[Line:0 Position:0] ---&gt; System.Windows.Markup.XamlParseException:[Line:0 Position:0] ---&gt; System.Windows.Markup.XamlParseException:[Line:0 Position:0] ---&gt; System.Windows.Markup.XamlParseException:[Line:0 Position:0] ---&gt; System.Windows.Markup.XamlParseException:[Line:0 Position:0] 在MS.Internal.XcpImports.CheckHResult(UInt32 hr) 在MS.Internal.XcpImports.SetValue(IManagedPeerBase obj,DependencyProperty属性,DependencyObject doh) 在System.Windows.DependencyObject.SetValue(DependencyProperty属性,DependencyObject doh) 在System.Windows.Controls.ListBox.GetContainerForItemOverride() 在System.Windows.Controls.ItemsControl.MS.Internal.Controls.IGeneratorHost.GetContainerForItem(Object item,DependencyObject recycledContainer) 在System.Windows.Controls.ItemContainerGenerator.Generator.GenerateNext(Boolean stopAtRealized,Boolean&amp; isNewlyRealized) 在System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.Primitives.IItemContainerGenerator.GenerateNext(Boolean&amp; isNewlyRealized) 在System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(大小约束) 在System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget,Double inWidth,Double inHeight,Double&amp; outWidth,Double&amp; outHeight) ---内部异常堆栈跟踪结束--- 在MS.Internal.XcpImports.CheckHResult(UInt32 hr) 在MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement元素,Size availableSize) 在System.Windows.Controls.ScrollContentPresenter.MeasureOverride(大小约束) 在System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget,Double inWidth,Double inHeight,Double&amp; outWidth,Double&amp; outHeight) ---内部异常堆栈跟踪结束--- 在MS.Internal.XcpImports.CheckHResult(UInt32 hr) 在MS.Internal.XcpImports.UIElement_Measure(UIElement元素,Size availableSize) 在System.Windows.UIElement.Measure(Size availableSize) 在System.Windows.Controls.ScrollViewer.MeasureOverride(大小约束) 在System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget,Double inWidth,Double inHeight,Double&amp; outWidth,Double&amp; outHeight) ---内部异常堆栈跟踪结束--- 在MS.Internal.XcpImports.CheckHResult(UInt32 hr) 在MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement元素,Size availableSize) 在System.Windows.FrameworkElement.MeasureOverride(Size availableSize) 在System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget,Double inWidth,Double inHeight,Double&amp; outWidth,Double&amp; outHeight) ---内部异常堆栈跟踪结束--- 在MS.Internal.XcpImports.CheckHResult(UInt32 hr) 在MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement元素,Size availableSize) 在System.Windows.FrameworkElement.MeasureOverride(Size availableSize) 在System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget,Double inWidth,Double inHeight,Double&amp; outWidth,Double&amp; outHeight) ---内部异常堆栈跟踪结束--- 在MS.Internal.XcpImports.CheckHResult(UInt32 hr) 在MS.Internal.XcpImports.FrameworkElement_MeasureOverride(FrameworkElement元素,Size availableSize) 在Microsoft.Phone.Controls.PhoneApplicationFrame.MeasureOverride(Size availableSize) 在System.Windows.FrameworkElement.MeasureOverride(IntPtr nativeTarget,Double inWidth,Double inHeight,Double&amp; outWidth,Double&amp; outHeight) ---内部异常堆栈跟踪结束---}
从Stack-Trace看,如果我缺少控件的宽度/高度,可能会出现,但我也尝试设置这些,但没有任何效果。我有什么问题吗?或者你能建议一个更好的方法来制作通用的CustomListBoxItem吗?
感谢您的期待,
的问候,
答案 0 :(得分:2)
CustomListboxItem样式的资源字典键是FilterListBoxItemStyle
:
<Style x:Key="FilterListBoxItemStyle" TargetType="controls:CustomListboxItem">
但您使用FilterListBoxStyle
来引用样式资源:
<ListBox ... ItemContainerStyle="{StaticResource FilterListBoxStyle}">
将上述声明更改为
<ListBox ... ItemContainerStyle="{StaticResource FilterListBoxItemStyle}">
<强>更新强>
话虽如此,还有另外一件事要提。为了拥有自定义派生的ListBoxItem类,您不能简单地在ItemTemplate
中的DataTemplate中使用它。相反,您还可以创建一个自定义派生的ListBox类来覆盖GetContainerForItemOverride方法:
public class CustomListBox : ListBox
{
protected override DependencyObject GetContainerForItemOverride()
{
return new CustomListboxItem();
}
}
自定义ListBox不再声明ItemTemplate
:
<controls:CustomListBox ...
ItemContainerStyle="{StaticResource FilterListBoxItemStyle}" />
您还可以在CustomListboxItem样式中设置NormalBackground
和SelectedBackground
属性。
答案 1 :(得分:0)
使用派生类进行分配。按如下方式修改FilterListBoxItemStyle
:
将TargetType
更改为ListBoxItem
制作SelectedBackground
和NormalBackground
动态资源
(例如:Background="{DynamicResource NormalBackground}"
)
从动画中移除Storyboard.TargetName="ContentContainer"
。
....
然后在每个页面(或您需要的任何范围)上根据需要定义动态资源:
<ListBox Grid.Row="1" ItemsSource="{Binding CyclesList}" ItemContainerStyle="{StaticResource FilterListBoxItemStyle}" >
<ListBox.Resources>
<SolidColorBrush Color="Transparent"
x:Key="NormalBackground" />
<SolidColorBrush Color="Red"
x:Key="SelectedBackground" />
</ListBox.Resources>
</ListBox>