【问题标题】:How to get selection of DataGrid SelectionMode="Extended" SelectionUnit="Cell" Binded to DataTable如何选择绑定到 DataTable 的 DataGrid SelectionMode="Extended" SelectionUnit="Cell"
【发布时间】:2016-07-24 21:35:57
【问题描述】:

我似乎只能找到具有 ObservableCollections 和自动生成列的解决方案,但我没有固定数量的列。这就是我使用 DataTable 绑定到 DataGrid 的原因。我不知道是否有可能使嵌套集合绑定有点像这样:

public ObservableCollection<RowData> Rows { get; set;}
public Class RowData
{
   public String ColumnName {get; set;}  
   public ObservableCollection<CellModel> Cells { get; set;}
}

到数据网格。

我尝试使用此answer,但附加属性不会更新选定单元格,我相信它是因为我使用的是 DataTable。以防它不让我发布一些代码。 它所做的基本上是显示 excel 表,因此它在一个选项卡内。

 <TabControl TabStripPlacement="Bottom"
                            Height="400" Width="700"
                            ItemsSource="{Binding SheetTabs}"
                            SelectedValue="{Binding SelectedTab}">
                    <TabControl.ItemTemplate>
                        <DataTemplate>
                            <TextBlock
                                Text="{Binding SheetName}" />
                        </DataTemplate>
                    </TabControl.ItemTemplate>
                    <TabControl.ContentTemplate>
                        <DataTemplate>
                            <DataGrid  
                          ItemsSource="{Binding SheetData}"
                                SelectionUnit="Cell"
                                Behaviors:DataGridHelper.SelectedCells="{Binding Path=CellSelections,  Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                SelectionMode="Extended"
                                 LoadingRow="DataGrid_LoadingRow"
                                RowHeaderWidth="30">

                            </DataGrid>
                        </DataTemplate>
                    </TabControl.ContentTemplate>
                </TabControl>

绑定的是这个类的 ObservableCollection:

public class SheetViewModel : BaseViewModel
{
    public string SheetName { get; set; }
    public DataTable SheetData { get; set; }
    private IList<DataGridCellInfo> _cellSelection;
    public IList<DataGridCellInfo> CellSelections {
        get
        {
            return _cellSelection;
        }
        set
        {
            _cellSelection = value;
            NotifyPropertyChange("CellSelections");
        }
    }

}

我正在使用的被攻击的财产看起来像这样,它是从here偷来的。

#region SelectedCells
    public static IList<DataGridCellInfo> GetSelectedCells(DependencyObject obj)
    {
        return (IList<DataGridCellInfo>)obj.GetValue(SelectedCellsProperty);
    }
    public static void SetSelectedCells(DependencyObject obj, IList<DataGridCellInfo> value)
    {
        obj.SetValue(SelectedCellsProperty, value);
    }
    public static readonly DependencyProperty SelectedCellsProperty =
        DependencyProperty.RegisterAttached("SelectedCells", typeof(IList<DataGridCellInfo>), typeof(DataGridHelper), new UIPropertyMetadata(null, OnSelectedCellsChanged));
    static SelectedCellsChangedEventHandler GetSelectionChangedHandler(DependencyObject obj)
    {
        return (SelectedCellsChangedEventHandler)obj.GetValue(SelectionChangedHandlerProperty);
    }
    static void SetSelectionChangedHandler(DependencyObject obj, SelectedCellsChangedEventHandler value)
    {
        obj.SetValue(SelectionChangedHandlerProperty, value);
    }
    static readonly DependencyProperty SelectionChangedHandlerProperty =
        DependencyProperty.RegisterAttached("SelectedCellsChangedEventHandler", typeof(SelectedCellsChangedEventHandler), typeof(DataGridHelper), new UIPropertyMetadata(null));

    //d is MultiSelector (d as ListBox not supported)
    static void OnSelectedCellsChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
    {
        if (GetSelectionChangedHandler(d) != null)
            return;

        if (d is DataGrid)//DataGrid
        {
            DataGrid datagrid = d as DataGrid;
            SelectedCellsChangedEventHandler selectionchanged = null;
            foreach (var selected in GetSelectedCells(d) as IList<DataGridCellInfo>)
                datagrid.SelectedCells.Add(selected);

            selectionchanged = (sender, e) =>
            {
                SetSelectedCells(d, datagrid.SelectedCells);
            };
            SetSelectionChangedHandler(d, selectionchanged);
            datagrid.SelectedCellsChanged += GetSelectionChangedHandler(d);
        }
        //else if (d is ListBox)
        //{
        //    ListBox listbox = d as ListBox;
        //    SelectionChangedEventHandler selectionchanged = null;

        //    selectionchanged = (sender, e) =>
        //    {
        //        SetSelectedCells(d, listbox.SelectedCells);
        //    };
        //    SetSelectionChangedHandler(d, selectionchanged);
        //    listbox.SelectionChanged += GetSelectionChangedHandler(d);
        //}
    }

编辑:

我注意到附加行为的构造函数仅被触发,即使应该有 4 个网格视图,每个选项卡 1 个。所以问题可能与标签的插入方式有关。

【问题讨论】:

    标签: c# wpf xaml datagrid datatable


    【解决方案1】:

    在将新列表添加到绑定项目之前,我没有意识到它永远不会起作用,选择会起作用。

    所以基本上它在边界

    Behaviors:DataGridHelper.SelectedCells="{Binding Path=CellSelections,  Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
    

    在视图模型中我只需要放一个;

    CellSelections = new List<DataGridCellInfo>();
    

    在附加属性真正起作用之前。

    我设法创建了一个带有动态对象的 Observable Collection,查找 ExpandoObject,以便在此处 og stackoverflow 上发表大量关于主题的帖子。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-21
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      • 2011-10-12
      • 2014-01-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多