如何滚动到 wpf mvvm 中数据网格中新添加的行

问题描述 投票:0回答:3

我有一个绑定可观察集合的数据网格。当我单击添加新按钮时,我会将新行添加到集合中。我如何实用地滚动到新行。

数据网格XMAL

<DataGrid SelectedIndex="{Binding SelectedIntex}" IsEnabled="{Binding IsKeySet}" CanUserDeleteRows="False" CanUserAddRows="False" Name="dgwTemplateDetails" SelectionMode="Single" ItemsSource="{Binding OrderTemplateList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedOrderTemplate}" IsReadOnly="False" AutoGenerateColumns="False" Width="auto">

      <DataGrid.Columns>
                            <DataGridTextColumn Header="Srl No" Visibility="Hidden" Binding="{Binding SrlNo}"/>
                            <DataGridTextColumn Header="Act Code" Width="75" Binding="{Binding ActCode, UpdateSourceTrigger=PropertyChanged}"/>
                            <DataGridTextColumn Header="Act Name" Width="275" Binding="{Binding ActName, UpdateSourceTrigger=PropertyChanged}"/>
                            <DataGridTextColumn Header="No. Of Days" Width="75" Binding="{Binding NoOfDays, UpdateSourceTrigger=PropertyChanged}"/>
                            <DataGridCheckBoxColumn Header="Is Cutting" Width="75" Binding="{Binding IsCutSelected, UpdateSourceTrigger=PropertyChanged}" />

        </DataGrid.Columns>
                    </DataGrid>

VM 添加行功能

if (ValidateHeader())
{
  if (OrderTemplateList == null)
    this.OrderTemplateList = new ObservableCollection<EventManagementTemplate>();
  EventManagementTemplate obJEvent = new EventManagementTemplate();
  obJEvent.BuyerCode = this.BuyerCode;
  this.OrderTemplateList.Add(obJEvent);
  int no = 1;
  this.OrderTemplateList.ToList().ForEach(m => m.SrlNo = no++);
}
c# wpf mvvm datagrid observablecollection
3个回答
2
投票

您需要执行以下操作:

  1. 为您的 dataGrid 命名,以便您可以在代码隐藏文件(与包含数据网格的 xaml 文件配对的 .cs 文件)中访问它

  2. 向您的视图模型添加一个委托,以供 AddRow 函数调用 - 该委托应将您想要滚动到视图中的对象作为参数。

  3. 让包含数据网格的背后代码订阅委托==>基本上,背后的代码是提供对视图模型的回调。回调后面的代码将是滚动到新项目的代码。

  4. 回调应调用数据网格的 ScrollIntoView 函数 (http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.scrollintoview(v=vs.110).aspx)

  5. 在视图模型的添加行函数结束时(添加项目后),使用要滚动到视图中的项目调用委托。

示例代码:

public class MyViewModel
{
   // declare the delegate signature...
   delegate void ScrollIntoViewDelegateSignature(EventManagementTemplate objEvent);

   // create a pointer to the delegate that can be set by the code behind...
   public ScrollIntoViewDelegateSignature ScrollIntoView {get; set;}

   protected AddRow()
   {
      .. your code here

      // call the delegate...
      if (ScrollIntoView != null)
         ScrollIntoView(objEvent)
   }
}

public class MyControlOrWindowThatContainsDataGrid : UserControl/ChildWindow/Page
{
   public void Initialize()
   {
      ...your code here
      // set the scrollIntoView delegate...
      myViewModel.ScrollIntoView = ScrollIntoView;
   }

   // create a ScrollIntoView function
   // ==> the return value and parameters MUST match the delegate signature
   public void ScrollIntoView(EventManagementTemplate objEvent)
   {
      myDataGrid.ScrollIntoView(objEvent);
   }
}

参考 http://msdn.microsoft.com/en-us/library/900fyy8e.aspx

我认为最好使用事件来做到这一点,但这更复杂。 以下是有关如何使用事件的 msdn 文档:http://msdn.microsoft.com/en-us/library/awbftdfh.aspx


0
投票

您可以为 DataGrid 创建行为。在此代码中,仅当新行添加到集合中时,它才会滚动到网格的最后一行。您可以根据任何条件修改它。有时需要添加一些延迟。如果不需要,您可以排除。

public class AutoScrollToEndBehavior : Behavior<DataGrid>
{
    private DateTime _lastCollectionChangedTime = DateTime.MinValue;

    protected override void OnAttached()
    {
        base.OnAttached();
        SubscribeToCollectionChanged();
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        UnsubscribeFromCollectionChanged();
    }

    private void SubscribeToCollectionChanged()
    {
        if (AssociatedObject.Items is ICollectionView collectionView)
        {
            collectionView.CollectionChanged += OnCollectionChanged;
        }
    }

    private void UnsubscribeFromCollectionChanged()
    {
        if (AssociatedObject.Items is ICollectionView collectionView)
        {
            collectionView.CollectionChanged -= OnCollectionChanged;
        }
    }

    private void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            _lastCollectionChangedTime = DateTime.Now;
            Task.Delay(100).ContinueWith(_ =>
            {
                if ((DateTime.Now - _lastCollectionChangedTime).TotalMilliseconds > 100)
                {
                    ScrollToEnd();
                }
            }, TaskScheduler.FromCurrentSynchronizationContext());
        }
    }

    private void ScrollToEnd()
    {
        if (AssociatedObject.Items.Count > 0)
        {
            var lastItem = AssociatedObject.Items[AssociatedObject.Items.Count - 1];
            AssociatedObject.Dispatcher.Invoke(() =>
            {
                AssociatedObject.ScrollIntoView(lastItem);
            });
        }
    }
}

在 XAML 中,

在 datagrid () 的结束标记上方添加以下代码

     <b:Interaction.Behaviors>
          <behavior:AutoScrollToEndBehavior/>
      </b:Interaction.Behaviors>
</DataGrid>

-2
投票

在 DataGrid 中添加项目后尝试此操作:

dgwTemplateDetails.ScrollIntoView(obJEvent);

此行将滚动到当前添加的元素。

© www.soinside.com 2019 - 2024. All rights reserved.