我有一个绑定可观察集合的数据网格。当我单击添加新按钮时,我会将新行添加到集合中。我如何实用地滚动到新行。
数据网格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++);
}
您需要执行以下操作:
为您的 dataGrid 命名,以便您可以在代码隐藏文件(与包含数据网格的 xaml 文件配对的 .cs 文件)中访问它
向您的视图模型添加一个委托,以供 AddRow 函数调用 - 该委托应将您想要滚动到视图中的对象作为参数。
让包含数据网格的背后代码订阅委托==>基本上,背后的代码是提供对视图模型的回调。回调后面的代码将是滚动到新项目的代码。
回调应调用数据网格的 ScrollIntoView 函数 (http://msdn.microsoft.com/en-us/library/system.windows.controls.datagrid.scrollintoview(v=vs.110).aspx)
在视图模型的添加行函数结束时(添加项目后),使用要滚动到视图中的项目调用委托。
示例代码:
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
您可以为 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>
在 DataGrid 中添加项目后尝试此操作:
dgwTemplateDetails.ScrollIntoView(obJEvent);
此行将滚动到当前添加的元素。