数据网格排序,行发生了什么

本文关键字:发生了 什么 排序 数据网 网格 数据 | 更新日期: 2023-09-27 18:27:42

我正在编写一个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个事件)。

在我的主窗口中,我像这样使用我的MarkedScrollBar:

<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事件,来自这里的代码)。

现在我的问题是,当我在MarkedScrollBar内对数据网格进行排序时,我希望标记紧跟在内容后面,标记绑定到内容。

第一次尝试,我尝试将标记与Dictionary Key=mark、Value=control的控件链接。我得到了DatagridRow,我想为我的数据上下文做一个标记。

第一次出现数据网格时,我的标记都很好,但如果我排序,我的记号就不会跟随。我进行了调试,发现有一个DataGridRow包含我的数据上下文项,但它不是我保存在字典中的那个。

结束首次尝试

第二次尝试,由于排序时DataGridRow发生了更改,我认为如果我将DataContext项链接到标记,它会修复错误。

所以现在,当我对我的数据网格进行排序时,我试图找到包含我的数据上下文项的数据网格。但它确实能找到任何东西。

但是,当我用窗口中的按钮手动重新执行相同的代码时,它就工作了。我所有的标记都出现在好的位置。

结束第二次尝试

关于我的延期的简要说明:

  • DataGrid:我用它来获取Sorted事件,因为在Sorting事件中,行还没有移动
  • ContentPresenter:我在上面添加事件来修改内容,但不修改属性(比如数据网格排序)。为此,我需要检查内容的类型,所以我现在不支持所有内容

我对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; }
    }
}

为了支持一个控件,我必须在这里添加它们。在加载该控件时,我会检查内容,如果内容是我在事件Sorted上的Datagrid,我会调用我的event ContentUpdated,以便能够更新我的标记。但此时此刻,我的数据网格中似乎没有包含包含数据上下文项的行。

数据网格排序,行发生了什么

启用虚拟化后,将只为实际在视图中的数据项生成行元素。您需要将标记与基础数据项(行对象)相关联,而不是与DataGridRow元素相关联。DataGrid上的Items属性应使行处于正确排序的位置。