我的问题是如何在ItemsSource
内引用Window
我已设置的Style
?我有以下ListViews
:
AppointmentOverview.xaml
<ListView Grid.Column="1" Grid.Row="3" ItemsSource="{Binding Mov}"/>
<ListView Grid.Column="1" Grid.Row="4" ItemsSource="{Binding Mon}"/>
<ListView Grid.Column="2" Grid.Row="3" ItemsSource="{Binding Div}"/>
<ListView Grid.Column="2" Grid.Row="4" ItemsSource="{Binding Din}"/>
<ListView Grid.Column="3" Grid.Row="3" ItemsSource="{Binding Miv}"/>
<ListView Grid.Column="3" Grid.Row="4" ItemsSource="{Binding Min}"/>
<ListView Grid.Column="4" Grid.Row="3" ItemsSource="{Binding Dov}"/>
<ListView Grid.Column="4" Grid.Row="4" ItemsSource="{Binding Don}"/>
<ListView Grid.Column="5" Grid.Row="3" ItemsSource="{Binding Frv}"/>
<ListView Grid.Column="5" Grid.Row="4" ItemsSource="{Binding Frn}"/>
正如您所看到的,每个ListView
都有不同的ItemsSource
,因此我无法通过ItemsSource
设置Style
。但他们都有相同的Style
。此Style
应包含Composite Collection
。 Composite Collection
应包含此ItemsSource
+一个Button
。我的问题是如何告诉CollectionViewSource
它应该使用已设置的ItemsSource
?我的Styles
位于不同的文件中。
Styles.xaml
<Style TargetType="{x:Type ListView}">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<UniformGrid Rows="5" Columns="1"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
</Style>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Border BorderBrush="#5076A7" BorderThickness="1">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FFFFFF" Offset="0.0"/>
<GradientStop Color="#C0D3EA" Offset="1.0"/>
</LinearGradientBrush>
</Border.Background>
<StackPanel TextElement.FontFamily="Segoe UI" TextElement.FontSize="12">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="15"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Padding="3,0,0,0" Text="{Binding Betreff}" TextTrimming="CharacterEllipsis" Grid.Column="0" Grid.Row="0"/>
<Button FontSize="7" Content="X" Grid.Column="1" Grid.Row="0"
Command="{Binding DataContext.DeleteButtonCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
CommandParameter="{Binding ItemId}"/>
</Grid>
<TextBlock Padding="3,0,0,0" Text="{Binding Kunde}"/>
<StackPanel Orientation="Horizontal">
<TextBlock FontWeight="Bold" Padding="3,0,0,0" Text="{Binding Ort}"/>
<TextBlock Padding="3,0,0,0" Text="("/>
<TextBlock Text="{Binding Alternative}"/>
<TextBlock Text=")"/>
</StackPanel>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<DataTrigger Binding="{Binding Betreff}" Value="Blocked">
<Setter Property="Template" Value="{StaticResource BlockedListViewItem}"/>
</DataTrigger>
</Style.Triggers>
</Style>
答案 0 :(得分:0)
您可以创建一个附加属性,该属性将保留初始集合,以避免与将在样式中注入的集合冲突。您必须创建一个新的DependencyObject类或在现有类中定义它:
public class Extensions : DependencyObject
{
#region MyItemsSource
/// <summary>
/// MyItemsSource Attached Dependency Property
/// </summary>
public static readonly DependencyProperty MyItemsSourceProperty =
DependencyProperty.RegisterAttached("MyItemsSource", typeof(IEnumerable), typeof(Extensions),
new FrameworkPropertyMetadata((IEnumerable)null));
/// <summary>
/// Gets the MyItemsSource property. This dependency property
/// indicates ....
/// </summary>
public static IEnumerable GetMyItemsSource(DependencyObject d)
{
return (IEnumerable)d.GetValue(MyItemsSourceProperty);
}
/// <summary>
/// Sets the MyItemsSource property. This dependency property
/// indicates ....
/// </summary>
public static void SetMyItemsSource(DependencyObject d, IEnumerable value)
{
d.SetValue(MyItemsSourceProperty, value);
}
#endregion
}
现在在XAML中,ListView将如下所示:
<ListView local:Extensions.MyItemsSource="{Binding Items}" Style="{StaticResource ListBox_Style}"/>
要将ItemsSource实际绑定到CompositeCollection中的MyItemsSource属性,没有简单的解决方案。 compositeCollection不是Visual对象,甚至不是DependencyProperty,因此不能使用findAncestor绑定。在这种情况下,使用CollectionViewSource作为样式的资源将不起作用。
这里需要一些解决方法。一种可能性是使用转换器:
public class CollectionConverter : IValueConverter
{
public ControlTemplate AdditionalControlTemplate { get; set; }
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
CompositeCollection cc = new CompositeCollection();
//Add base ItemSource
CollectionContainer cont = new CollectionContainer();
cont.Collection = (IEnumerable)value;
cc.Add(cont);
//Add a control at the end
if(AdditionalControlTemplate != null)
cc.Add(new Control() { Template = AdditionalControlTemplate });
return cc;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
此转换器获取源集合并将其注入CompositeCollection。然后使用可在转换器外指定的模板将控件添加到此集合中。所以你的按钮可以进入这个ControlTemplate。 ListView样式将如下所示:
<Style x:Key="ListBox_Style" TargetType="{x:Type ListView}">
<Style.Resources>
<!-- Control template for the object to be added at the end of the ListView -->
<ControlTemplate x:Key="AdditionalButtonTemplate" TargetType="{x:Type Control}">
<Button Content="Hello World!"/>
</ControlTemplate>
<local:CollectionConverter x:Key="CollectionConverter" AdditionalControlTemplate="{StaticResource AdditionalButtonTemplate}"/>
</Style.Resources>
<Setter Property="ItemsSource" Value="{Binding (local:Extensions.MyItemsSource), Converter={StaticResource CollectionConverter}, RelativeSource={RelativeSource Self}}"/>
</Style>
绕过CompositeCollection限制的更简单的解决方案是使用中间ItemsControl。因此,您将使用ItemsControl而不是ListView:
使用以下样式:
<Style x:Key="icListViewStyle" TargetType="{x:Type ItemsControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ItemsControl}">
<ListView>
<ListView.Resources>
<CollectionViewSource x:Key="BaseItemsSource" Source="{Binding ItemsSource, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}, AncestorLevel=2}}"/>
</ListView.Resources>
<ListView.ItemsSource>
<CompositeCollection>
<CollectionContainer Collection="{Binding Source={StaticResource BaseItemsSource}}"/>
<Button Content="Hello World!"/>
</CompositeCollection>
</ListView.ItemsSource>
</ListView>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这里BaseItemsSource是ListView的资源,它是一个实际的可视对象,因此可以在绑定中解析RelativeSource。