Data binding ';数据绑定完成';Silverlight 4.0 DataGrid的事件?

Data binding ';数据绑定完成';Silverlight 4.0 DataGrid的事件?,data-binding,silverlight-4.0,Data Binding,Silverlight 4.0,我有一个绑定到属性的DataGrid: <cd:DataGrid Name="myDataGrid" ItemsSource="{Binding Mode=OneWay,Path=Thingies}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"> ... ... 当Thingies属性更改时,一旦数据网格中的所有行都填充了Thingies的新内

我有一个绑定到属性的DataGrid:

<cd:DataGrid 
    Name="myDataGrid"
    ItemsSource="{Binding Mode=OneWay,Path=Thingies}"
    VerticalScrollBarVisibility="Auto" 
    HorizontalScrollBarVisibility="Auto">
...

...
Thingies
属性更改时,一旦数据网格中的所有行都填充了
Thingies
的新内容,我希望数据网格滚动到底行

在WinForms中,我可以通过订阅DataBindingComplete事件来实现这一点。MSDN论坛包含了一些关于如何使用Silverlight 4.0实现这一点的建议,但这些建议的范围从完全邪恶到纯粹愚蠢:

  • 在加载时启动一个100毫秒计时器,并在计时器运行时滚动
  • 添加行时对行进行计数,当添加的行数等于数据源中的实体数时,滚动到底部

在Silverlight 4.0中是否有一种惯用的、优雅的方式来实现我想要的功能?

使用ScrollIntoView方法来实现这一点

myDataGrid.ItemSource = Thingies;
myDataGrid.UpdateLayout();
myDataGrid.ScrollIntoView(MyObservableCollection[MyObservableCollection.Count - 1], myDataGrid.Columns[1]);

你不需要为此举办任何特别活动

为什么不从
DataGrid
派生并创建自己的
ItemsSourceChanged
事件

       public class DataGridExtended : DataGrid
       {
            public delegate void ItemsSourceChangedHandler(object sender, EventArgs e);

            public event ItemsSourceChangedHandler ItemSourceChanged;

            public new System.Collections.IEnumerable ItemsSource
            {
                get { return base.ItemsSource; }
               set
               {
                   base.ItemsSource = value; 

                   EventArgs e = new EventArgs();
                   OnItemsSourceChanged(e);
               }
           }

           protected virtual void OnItemsSourceChanged(EventArgs e)
           {
               if (ItemSourceChanged != null)
                   ItemSourceChanged(this, e);
           }
       }

我在寻找解决同一问题的方法时偶然发现了这一点。我发现,当我尝试在筛选和排序更改后将所选项目滚动到视图中时,我经常收到一个运行时错误(索引超出范围)。我本能地知道这是因为网格在那个特定时刻没有填充

亚伦的建议对我很管用。定义网格后,我将添加一个事件侦听器:

_TheGrid.LayoutUpdated += (sender, args) => TheGrid.ScrollIntoView(TheGrid.SelectedItem, TheGrid.CurrentColumn);

这解决了我的问题,并且似乎在参数为null时也会自动退出。

我认为在xaml中,最好的方法是使用绑定
NotifyOnTargetUpdated=true
,然后您可以将
TargetUpdated
挂接到您选择的任何事件

<ThisControl BindedProperty="{Binding xxx, NotifyOnTargetUpdated=true}"
             TargetUpdated="BindingEndedHandler">


Harish,我的理解是设置ItemSource会导致绑定异步发生。这意味着在您提供的代码示例中,可以在绑定集合中的最后一个对象之前调用ScrollIntoView()。这就是为什么我需要一个事件来指示绑定已完成。请尝试将数据绑定语句放在Try-catch语句中。除此之外,让您的语句滚动到最后一条记录。好主意,但我需要知道绑定何时完成,即绑定的项目何时在网格中呈现尽可能多。很可能在渲染完成之前触发ItemSourceChanged事件。@Duncan您是否已经使用了LayoutUpdated事件,并在触发时进行了记录?它可能会在呈现ItemsSource更改后触发,这将提供您所需的钩子。似乎是针对WPF,而不是silverlight?