我怎么可以加载控件不会阻塞UI绑定? [英] How i can make loading controls in Binding without blocking UI?

查看:202
本文介绍了我怎么可以加载控件不会阻塞UI绑定?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这种情况:

我想,当我进入到人收藏的幻灯片应该等待加载完成,然后我可以看到完整的名单,我有follwing在我的视图模型加载集合中的主窗口,我有一个大的数据,因此:

i want to load a collection in my ViewModel in the MainWindow i have a big data so when i enter to the slide of people collection it should wait to finish loading then i can see the full list, i have the follwing:


  • 在XAML code我有:

  • in the xaml code i have:

<ListView ..... 
ItemsSource{Binding PeopleList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}
... />


  • 和在视图模式我有:

  • and in the viewmode i have:

    // ...
    private ObservableCollection<Person> _People;
    public ObservableCollection<Person> People
    { get{return _People;} set{ _People = value; RaisePropertyChange("People");}}
    // ...
    


  • 和我想通过一个负载第一个完全开始加载第二次...等之后加载所有的人列表中的一个不阻塞,我想在主窗口我的窗口是这样的:

    and i want to load all the people list one by one after load the first one completely start loading the second ... etc without blocking the mainwindow i want my window looks like:

    我累了做我自己,但我失败了。之前的感谢。

    i tired to do it my self but i fail. thanks before.

    推荐答案

    有存在从另一个线程修改视图中,使用的SynchronizationContext方式。

    There exist ways for to modify view from another thread, using the SynchronizationContext.

    请参见下面的例子:

            private void Button_Click(object sender, RoutedEventArgs e)
            {
                var sync = SynchronizationContext.Current;
                BackgroundWorker w = new BackgroundWorker();
                w.DoWork+=(_, __)=>
                    {
                        //sync.Post(p => { button.Content = "Working"; }, null);
                        int j = 0;
                        for (int i = 0; i < 10; i++)
                        {
                            j++;
                            sync.Post(p => { button.Content = j.ToString(); }, null);
                            Thread.Sleep(1000);
                        }
                        sync.Post(p => { button.Background = Brushes.Aqua; button.Content = "Some Content"; }, null);
                    };
                w.RunWorkerAsync();
            }
    

    和本所认为:

    <Window x:Class="WpfApplication2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Button x:Name="button" Content="Some Content" Click="Button_Click"/>
        </Grid>
    </Window>
    

    此code,更新数次视图(在这种情况下,按钮)。我觉得这解决您最初的问题。

    This code, updates several times the view (a button in this case). I think this solve your initial question.

    ---- ----编辑

    这是使用这种思想的一个更​​好的方法:我建议在基本视图模型来创建这样一个方法:

    This is a better way of using this idea: I propose to create a method like this in a base view model:

        public void LockAndDoInBackground(Action action, string text, Action beforeVisualAction = null, Action afterVisualAction = null)
        {
            if (IsBusy)
                return;
            var currentSyncContext = SynchronizationContext.Current;
            ActiveThread = new Thread((_) =>
            {                
                currentSyncContext.Send(t =>
                {
                    IsBusy = true;
                    BusyText = string.IsNullOrEmpty(text) ? "Wait please..." : text;
                    if (beforeVisualAction != null)
                        beforeVisualAction();
                }, null);
                action();
                currentSyncContext.Send(t =>
                {
                    IsBusy = false;
                    BusyText = "";
                    if (afterVisualAction != null)
                        afterVisualAction();
                }, null);
            });
            ActiveThread.Start();
        }
    

    在这样的任何子视图模型可以使用此为excecuting数据处理量很大,并且UI没有得到冻结。 IsBusy BusyText 是视图模型变量至极被绑定到视图等待消息,并等待元素的可见性。
    这是用在孩子视图模型的命令的例子:

    In this way any child view model can use this for excecuting big amount of data processing, and the UI does not get freeze. IsBusy and BusyText are the view models variables wich are bound to the View Wait Message and the Visibility of a Wait Element. This is an example of use in a child view model's command:

      private RelayCommand _SomeCommand;
      public RelayCommand SomeCommand
        {
            get { return _SomeCommand ?? (_SomeCommand = new RelayCommand(ExecuteSomeCommand, CanExecuteSomeCommand)); }
        }
    
        private void ExecuteSomeCommand()
        {
            Action t = ()=> 
            {
                //some action
            };
    
            LockAndDoInBackground(t, "Generating Information...");
        }
    
        private bool CanExecuteSomeCommand()
        {
            return SelectedItem != null;
        }
    

    希望这将成为一个更明显的例子。

    Hope this will become a more clear example.

    这篇关于我怎么可以加载控件不会阻塞UI绑定?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆