我创建了一个引用,将大数据加载到具有dapper扩展名的数据网格中。我有一个行为,它检测滚动然后使用此RelayCommand向下加载以下数据:
Datagrid属性中的XAML:
Behavior:ScrollViewerMonitor.AtEndCommand="{Binding LoadCommand}"
我的行为(滚动停止时检测到):
public class ScrollViewerMonitor
{
public static DependencyProperty AtEndCommandProperty
= DependencyProperty.RegisterAttached(
"AtEndCommand", typeof(ICommand),
typeof(ScrollViewerMonitor),
new PropertyMetadata(OnAtEndCommandChanged));
public static ICommand GetAtEndCommand(DependencyObject obj)
{
return (ICommand)obj.GetValue(AtEndCommandProperty);
}
public static void SetAtEndCommand(DependencyObject obj, ICommand value)
{
obj.SetValue(AtEndCommandProperty, value);
}
public static void OnAtEndCommandChanged(
DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement element = (FrameworkElement)d;
if (element != null)
{
element.Loaded -= element_Loaded;
element.Loaded += element_Loaded;
}
}
static void element_Loaded(object sender, RoutedEventArgs e)
{
FrameworkElement element = (FrameworkElement)sender;
element.Loaded -= element_Loaded;
ScrollViewer scrollViewer = FindChildOfType<ScrollViewer>(element);
if (scrollViewer == null)
{
// throw new InvalidOperationException("ScrollViewer not found.");
return;
}
var dpd = DependencyPropertyDescriptor.FromProperty(ScrollViewer.VerticalOffsetProperty, typeof(ScrollViewer));
dpd.AddValueChanged(scrollViewer, delegate (object o, EventArgs args)
{
bool atBottom = scrollViewer.VerticalOffset
>= scrollViewer.ScrollableHeight;
if (atBottom)
{
var atEnd = GetAtEndCommand(element);
if (atEnd != null)
{
atEnd.Execute(null);
}
}
});
}
static T FindChildOfType<T>(DependencyObject root) where T : class
{
var queue = new Queue<DependencyObject>();
queue.Enqueue(root);
while (queue.Count > 0)
{
DependencyObject current = queue.Dequeue();
for (int i = VisualTreeHelper.GetChildrenCount(current) - 1; 0 <= i; i--)
{
var child = VisualTreeHelper.GetChild(current, i);
var typedChild = child as T;
if (typedChild != null)
{
return typedChild;
}
queue.Enqueue(child);
}
}
return null;
}
}
我的带有LoadCommand的ViewModel:
//Init mmy ObservableCollection for DataGrid
var myObservableCollection = new ObservableCollection<Mouvement_Brouillard>();
//Init my Object
//Parameters(NumberPerPage,Conditions,OrderBy,Connection)
var myReference = new Paged2<Mouvement_Brouillard>(150, "", "Swmo_Id", new ConnectionProvider());
//Load First Datas
myReference.AddDatas(myObservableCollection);
//Call LoadCommand when Scroll is down
LoadCommand = new RelayCommand<object>(myReference.LoadCommand(myObservableCollection));
我的引用是Paged2(ObservableCollection中的AddData并执行LoadCommand:
public class Paged2<T>
{
private T Value { get; set; }
public int NumberPage { get; set; }
public int RowsPerPage { get; set; }
public string Conditions { get; set; }
public string OrderBy { get; set; }
public ConnectionProvider Cnn { get; set; }
public static bool Busy;
public Paged2(int _RowsPerPage, string _Conditions, string _OrdeBy, ConnectionProvider _Cnn)
{
this.RowsPerPage = _RowsPerPage;
this.Conditions = _Conditions;
this.OrderBy = _OrdeBy;
this.NumberPage = 1;
this.Cnn = _Cnn;
}
public async void AddDatas(ObservableCollection<T> myList)
{
IEnumerable<T> myNewBlocList;
//DAL
using (var myCnn = this.Cnn.GetOpenConnection())
{
myNewBlocList = await myCnn.GetListPagedAsync<T>(this.NumberPage, this.RowsPerPage, this.Conditions, this.OrderBy);
}
NumberPage++;
foreach (var Item in myNewBlocList)
myList.Add(Item);
}
public Action<object> LoadCommand(Ref<ObservableCollection<T>> myList)
{
return new Action<object>(
obj =>
{
if (Busy)
return;
Busy = true;
System.Threading.ThreadPool.QueueUserWorkItem(
delegate
{
Application.Current.Dispatcher.BeginInvoke(new Action(
delegate
{
AddDatas(myList);
Busy = false;
}));
});
});
}
public class Ref<T>
{
public Ref() { }
public Ref(T value) { Value = value; }
public T Value { get; set; }
public override string ToString()
{
T value = Value;
return value == null ? "" : value.ToString();
}
public static implicit operator T(Ref<T> r) { return r.Value; }
public static implicit operator Ref<T>(T value) { return new Ref<T>(value); }
}
}
一切正常但由于我外包(放在另一个文件中)方法LoadCommand代码的下一部分不再有效:
public Action<object> LoadCommand(Ref<ObservableCollection<T>> myList)
{
return new Action<object>(
obj =>
{
if (Busy)
return;
Busy = true;
System.Threading.ThreadPool.QueueUserWorkItem(
delegate
{
Application.Current.Dispatcher.BeginInvoke(new Action(
delegate
{
AddDatas(myList);
Busy = false;
}));
});
});
}