Datagrid排序,行怎么了?

时间:2014-10-23 21:09:44

标签: c# wpf xaml sorting datagrid

我正在编写一个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。但它确实发现了什么。

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

结束第二次尝试

我的扩展的简要说明:

  • DataGrid:我用它来获取Sorted事件,因为在Sorting事件中尚未移动的行。
  • ContentPresenter:我在其上添加事件以修改内容,但不修改属性(如datagrid排序)。为此我需要检查内容的类型,所以我暂时不支持所有内容。

我的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项目的行。

1 个答案:

答案 0 :(得分:0)

启用虚拟化后,将仅为实际可见的数据项生成行元素。您需要将标记与基础数据项(行对象)相关联,而不是DataGridRow元素。 Items上的DataGrid属性应该具有正确排序位置的行。