我有在XAML只具备一个WPF的ListView / GridView的。 第一列使用CellTemplate指定图标和其他人使用DisplayMemberBinding来填充自己。 图标列是20宽,图标16,但他们要通过利润/填充/东西截断。 其中,它的设置我不能工作了。
这里的要点(我已经删除了一些列,因为它们是相同的):
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
<Setter Property="FontWeight" Value="Normal" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<DataTemplate x:Key="image">
<Image Width="16" Height="16" Margin="0,0,0,0"
HorizontalAlignment="Center"
Source="{Binding Path=ObjectType,
Converter={StaticResource imageConverter} }" />
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Width="20"
CellTemplate="{StaticResource image}"/>
<GridViewColumn Width="120" Header="Name"
DisplayMemberBinding="{Binding Path=Name}"/>
</GridView>
</ListView.View>
ImageConverter只是变成一个对象类型为图像,以每种类型的项目都有自己的图标。
使用史努比搞清楚哪些元素是负责征收额外的间距。 将鼠标移到空间并按住控制和转移。 该元素将在随后的可视化树中突出显示。
在GridView的许多功能都被硬编码到类。 特别是GridViewRowPresenter对每个小区的创建一个硬编码的TextBlock或ContentPresenter容器,并迫使利润率6,0,6,0不管你喜欢还是不喜欢。
通常我会从任何涉及硬编码阴性切缘来补偿,因为它是分层的另一劈一劈你泄气。 然而,拆卸后GridViewRowPresenter,有没有其他的选择。
我的第一次尝试来覆盖这是在GridViewRowPresenter类创建的容器控件隐式的风格,但控制是一个TextBox或没有模板来覆盖ContentPresenter。
我的第二次尝试拆卸代码,并建立一个新的GridViewRowPresenter。 恐怕有太多的乱伦“内部”调用的类,使这个可行的解决方案。
更智能建筑师将已经提供了允许的类的用户覆盖这是对每个小区创建容器一个DependencyProperty。 出于某种原因,他们让这个与头但不是实际的单元格内容。
因此,我们留下了一个事实,即在GridRowPresenter细胞既不能被覆盖,逆向工程,也没有模板。 我很抱歉,但切缘阴性是可以与这个类中做的最好的。
我们需要一个更好的ListView:在GridView是不适合无外观界面,虽然我很欣赏他们原设计师试图通过从表示离婚的ItemsPresenter做。
默认情况下,每个小区具有6,0硬编码余量。 也许这是你的问题。 你可以在你的celltemplate设定-6,0保证金覆盖此行为
我开发了基于伊恩·格里菲思的黑客(的解决方案http://www.interact-sw.co.uk/iangblog/2007/05/30/wpf-listview-column-margins )。 控制执行以下操作:
- 设置由GridViewRowPresenter创造了TextBlock的或ContentPresenter硬编码到保证金此控件的填充依赖属性
- 传播这种控制的的HorizontalAlignment和VerticalAlignment其容器
- 复位保证金/填充的一个ListViewItem / GridViewRowPresenter容器。
所以,它给你一种价值观控制的这是硬编码。
码:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace Put.Your.Namespace.Here
{
/// <summary>
/// Class allows for reseting hard coded ListViewItem margins and paddings
/// </summary>
public class ListViewCustomizableCellPresenter : Decorator
{
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
base.OnVisualParentChanged(oldParent);
var cp = VisualTreeHelper.GetParent(this) as FrameworkElement;
if (cp != null)
{
cp.Margin = Padding;
cp.VerticalAlignment = VerticalAlignment;
cp.HorizontalAlignment = HorizontalAlignment;
}
ResetGridViewRowPresenterMargin();
ResetListViewItemPadding();
}
private T FindInVisualTreeUp<T>() where T : class
{
DependencyObject result = this;
do
{
result = VisualTreeHelper.GetParent(result);
}
while (result != null && !(result is T));
return result as T;
}
private void ResetGridViewRowPresenterMargin()
{
var gvrp = FindInVisualTreeUp<GridViewRowPresenter>();
if (gvrp != null)
gvrp.Margin = new Thickness(0);
}
private void ResetListViewItemPadding()
{
var lvi = FindInVisualTreeUp<ListViewItem>();
if (lvi != null)
lvi.Padding = new Thickness(0);
}
/// <summary>
/// Padding dependency property registration
/// </summary>
public static readonly DependencyProperty PaddingProperty =
DependencyProperty.Register("Padding", typeof(Thickness), typeof(ListViewCustomizableCellPresenter), new PropertyMetadata(default(Thickness)));
/// <summary>
/// Padding dependency property
/// </summary>
public Thickness Padding
{
get { return (Thickness)GetValue(PaddingProperty); }
set { SetValue(PaddingProperty, value); }
}
}
}
在XAML(内GridViewColumn的定义)使用示例:
<GridViewColumn.CellTemplate>
<DataTemplate>
<yourxamlnamespacehere:ListViewCustomizableCellPresenter Padding="0"
VerticalAlignment="Center">
<YourControlOrPanelHere />
</yourxamlnamespacehere:ListViewCustomizableCellPresenter>
</DataTemplate>
</GridViewColumn.CellTemplate>
由于余量是硬编码的常数,只有解决方案是使用的Reflexion用手去改变它。
在VB:
' Hack :
' Changes the default margin for the GridView's Column.
Dim GridViewCellMarginProperty = GetType(GridViewRowPresenter).GetField("_defalutCellMargin", BindingFlags.NonPublic Or BindingFlags.Static Or BindingFlags.GetField)
If (GridViewCellMarginProperty IsNot Nothing) Then
GridViewCellMarginProperty.SetValue(Nothing, New Thickness(2, 0, 2, 0))
End If
它工作正常,在我的项目。