我正在编写一个UserControl,可以用作带有颜色标记的ScrollBar(就像大多数所有IDE一样)。
我的UserControl外观
<UserControl x:Class="MarkedScrollBar" x:Name="Instance" ...>
<Grid Name="grd" >
<COLUMN/ROW DEF>...</>
<ScrollViewer Name="scrView" Grid.RowSpan="3" Grid.ColumnSpan="2" >
<my:IcuContentPresenter x:Name="presenter" Content="{Binding AdditionnalContent, ElementName=Instance}" ContentUpdated="presenter_ContentUpdated" />
</ScrollViewer>
<Canvas ...(Canvas place on the scrollbar) />
</Grid>
</UserControl>
在我的UserControl上,一切正常。我可以在我的IcuContentPresenter中添加内容(扩展ContentPresenter以获得1个以上的事件)。
在我的主窗口中,我使用我的MarkedScroolBar:
<my:IcuMarkedScrollBar Grid.Row="0" x:Name="bbb" Grid.Column="0" >
<my:IcuMarkedScrollBar.AdditionnalContent>
<my:IcuDataGrid ItemsSource="{Binding AAA, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" Loaded="DataGrid_Loaded" Width="300" LoadingRow="DataGrid_LoadingRow" />
</my:IcuMarkedScrollBar.AdditionnalContent>
</my:IcuMarkedScrollBar>
同样,我有一个DataGrid扩展来获得1个事件(Sorted事件,来自here的代码)。
现在我的问题是,当我对我的MarkedScrollBar中的数据网格进行排序时,我希望标记跟随标记绑定的内容。
第一次尝试,我尝试将标记与具有Dictionary Key = Mark,Value = Control的控件链接。我得到了DatagridRow,我想为我的datacontext标记。
第一次出现数据网格时,我的标记都很好,但如果我排序,我的标记就不会出现。我进入调试,看到有一个DataGridRow包含我的datacontext项目,但它不是我保存在我的词典中的那个。
结束首次尝试
第二次尝试,当我排序时DataGridRow发生了变化,我想如果我将我的DataContext项目链接到我的标记,它就会修复bug。
所以现在,当我对datagrid进行排序时,我尝试找到包含我的datacontext项的datagridrow。但它确实发现了什么。
但是,当我用窗口中的按钮手动重新执行相同的代码时,它就可以正常工作。我的所有标记都出现在好位置。
结束第二次尝试
我的扩展的简要说明:
我的ContentPresenter代码是:
public class IcuContentPresenter : ContentPresenter
{
public event EventHandler<ControlEventArgs> ContentUpdated;
public IcuContentPresenter()
{
this.Loaded += OnLoaded;
}
protected void OnLoaded(object p_oSender, RoutedEventArgs p_oEvent)
{
Type t = this.Content.GetType();
if (t == typeof(IcuDataGrid))
{
IcuDataGrid oControl = this.Content as IcuDataGrid;
oControl.Sorted += CallEvent;
}
}
void CallEvent(object sender, EventArgs e)
{
if (ContentUpdated != null)
{
ContentUpdated(this, new ControlEventArgs(Content.GetType()));
}
}
public UIElement FindVisualElementForObject(object p_oObject)
{
UIElement oTheOne = null;
if (Content.GetType() == typeof(IcuDataGrid))
{
oTheOne = FindInDatagrid(p_oObject);
}
return oTheOne;
}
private UIElement FindInDatagrid(Object p_oObj)
{
DataGrid oGrid = Content as DataGrid;
var a = (DataGridRow)oGrid.ItemContainerGenerator.ContainerFromItem(p_oObj);
return a;
}
//----------------------------------------------------
// Inner class
//----------------------------------------------------
public class ControlEventArgs : EventArgs
{
public ControlEventArgs(Type value)
{
ControlType = value;
}
public Type ControlType { get; set; }
}
}
要支持控件,我必须在此处添加它们。在加载此控件时,我检查内容,如果内容是我在事件上的Datagrid Sorted我调用我的事件ContentUpdated以便能够更新我的标记。但此时此刻,我的数据网格中没有包含我的datacontext项目的行。
答案 0 :(得分:0)
启用虚拟化后,将仅为实际可见的数据项生成行元素。您需要将标记与基础数据项(行对象)相关联,而不是DataGridRow
元素。 Items
上的DataGrid
属性应该具有正确排序位置的行。