这与Issues with alignment with selection in a listbox
有关我有一个用两个自定义控件替换ListBox - GridControl和GridItemControl。我看到的问题是两者之间没有任何联系,即当你向GridControl添加项目时,它们不是GridItemControl。我可以说,因为mousedown事件没有发生。
如果我使用XAML在GridControl中嵌入GridItemControl但是它与ItemSource不同,我确实看到了一个关联。
这是GridControl:
public class GridControl : Selector
{
static GridControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridControl), new FrameworkPropertyMetadata(typeof(GridControl)));
}
}
这是GridItemControl:
public class GridItemControl : ContentControl
{
public static readonly DependencyProperty BarProperty = DependencyProperty.Register(
"Bar",
typeof(int),
typeof(GridItemControl),
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public static readonly DependencyProperty TrackProperty = DependencyProperty.Register(
"Track",
typeof(int),
typeof(GridItemControl),
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public static readonly DependencyProperty PickedProperty = DependencyProperty.Register(
"Picked",
typeof(bool),
typeof(GridItemControl),
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public int Bar
{
get
{
return (int)this.GetValue(BarProperty);
}
set
{
SetValue(BarProperty, value);
}
}
public int Track
{
get
{
return (int)this.GetValue(TrackProperty);
}
set
{
SetValue(TrackProperty, value);
}
}
public bool Picked
{
get
{
return (bool)this.GetValue(PickedProperty);
}
set
{
SetValue(PickedProperty, value);
}
}
static GridItemControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(GridItemControl), new FrameworkPropertyMetadata(typeof(GridItemControl)));
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
base.OnMouseDown(e);
if (e.ChangedButton == MouseButton.Left)
{
this.Picked = true;
e.Handled = true;
}
}
}
这是Generic.xaml:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:PatternControlLibrary"
xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:Double x:Key="barWidth">30</system:Double>
<system:Double x:Key="trackHeight">24</system:Double>
<Style TargetType="{x:Type local:GridControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:GridControl}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<local:GridPanel VerticalAlignment="Top" BarWidth="{StaticResource barWidth}" TrackHeight="{StaticResource trackHeight}">
<local:GridPanel.Background>
<DrawingBrush TileMode="Tile" ViewboxUnits="Absolute" ViewportUnits="Absolute">
<DrawingBrush.Viewbox>
<Rect X="0" Y="0" Width="{StaticResource barWidth}" Height="{StaticResource trackHeight}"/>
</DrawingBrush.Viewbox>
<DrawingBrush.Viewport>
<Rect X="0" Y="0" Width="{StaticResource barWidth}" Height="{StaticResource trackHeight}"/>
</DrawingBrush.Viewport>
<DrawingBrush.Drawing>
<GeometryDrawing Brush="LightGray">
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="1"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<PathGeometry>
<PathFigure IsFilled="True">
<LineSegment>
<LineSegment.Point>
<Point X="{StaticResource barWidth}" Y="0"/>
</LineSegment.Point>
</LineSegment>
<LineSegment>
<LineSegment.Point>
<Point X="{StaticResource barWidth}" Y="{StaticResource trackHeight}"/>
</LineSegment.Point>
</LineSegment>
<LineSegment>
<LineSegment.Point>
<Point X="0" Y="{StaticResource trackHeight}"/>
</LineSegment.Point>
</LineSegment>
<LineSegment/>
</PathFigure>
</PathGeometry>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</local:GridPanel.Background>
</local:GridPanel>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:GridItemControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:GridItemControl}">
<Border>
<ContentPresenter />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="local:GridPanel.Bar" Value="{Binding Bar}"/>
<Setter Property="local:GridPanel.Track" Value="{Binding Track}"/>
</Style>
</ResourceDictionary>
如果我在MainWindow.xaml中使用以下内容,我会得到我期望的内容:
<Grid>
<cc:GridControl
ItemTemplate="{StaticResource dataItemTemplate}">
<cc:GridItemControl Content="Test" Bar="5" Track="3"/>
</cc:GridControl>
</Grid>
(根据Bar and Track,盒子没有对齐,但这是另一个问题!)。
如果我将其替换为我期望使用的内容:
<Grid>
<cc:GridControl
ItemsSource="{Binding Items}"
ItemTemplate="{StaticResource dataItemTemplate}"/>
</Grid>
然后没有使用GridItemControl,因为当我点击一个单元格时,我没有看到mousedown事件。
答案 0 :(得分:3)
如果您实现自定义ItemsControl
并想要使用自定义容器类型,则需要覆盖一些方法:
protected override DependencyObject GetContainerForItemOverride()
{
return new GridItemControl();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return (item is GridItemControl);
}
上述方法是ItemsControl
如何为基础数据项生成容器元素。例如,ListBox
会覆盖这些内容以提供ListBoxItem
个容器,而不是标准ContentControl
。
另外,如果您想坚持使用已接受的命名约定,GridItemControl
应该被称为GridControlItem
。