MVVM BeginInvoke在我的引用中不起作用

时间:2016-06-14 07:02:09

标签: c# wpf mvvm delegates threadpool

我创建了一个引用,将大数据加载到具有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;
                     }));
            });
     });
}

0 个答案:

没有答案