Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在加载另一个UI线程时更新UI线程_C#_Wpf_Multithreading - Fatal编程技术网

C# 在加载另一个UI线程时更新UI线程

C# 在加载另一个UI线程时更新UI线程,c#,wpf,multithreading,C#,Wpf,Multithreading,我正在尝试从第一个窗口(GUI_1)创建一个辅助窗口(GUI_2),并在GUI_1初始化时从GUI_2更新一个标签。(类似于加载屏幕) 我试过任务、工厂、调度员,但我认为我缺少了一些东西 public MainWindow() { InitializeComponent(); Task.Factory.StartNew(() => { DispatcherOperation op = Dispatcher.BeginInvoke((Action)(()

我正在尝试从第一个窗口(GUI_1)创建一个辅助窗口(GUI_2),并在GUI_1初始化时从GUI_2更新一个标签。(类似于加载屏幕)

我试过任务、工厂、调度员,但我认为我缺少了一些东西

public MainWindow()
{
   InitializeComponent();
   Task.Factory.StartNew(() =>
     {
        DispatcherOperation op = Dispatcher.BeginInvoke((Action)(() => {
           Window1 gui = new Window1();
           gui.Show();
        }));
     });
 }
这样,我的GUI_2就打开了,但是如果我试图更新标签,它只会显示最后一个值。(即:a表示线程的i=0到10。仅显示10值)

我怎样才能做到这一点

编辑: 我尝试过以下代码:

public partial class Loading : Window
{
    public static object uiContext;
    private List<string> paths;
    private List<Color>  colors;
    public Loading(List<string> _paths, List<Color> _colors)
    {
        InitializeComponent();
        paths = _paths;
        colors = _colors;
    }
    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        Storyboard s = (Storyboard)TryFindResource("sb");
        s.Begin();  // Start animation
        await Task.Run(() => EXCEL.Analogize(paths, this, colors));
        Close();
    }
    public void UpdateWindow(string text, int percent)
    {
        Dispatcher.Invoke(() =>
        {
            progress_label.Content = text;
            progress.Value = percent;
        });
    }
}
公共部分类加载:窗口
{
公共静态对象上下文;
私有列表路径;
私有列表颜色;
公共加载(列表路径、列表颜色)
{
初始化组件();
路径=_路径;
颜色=_颜色;
}
已加载专用异步无效窗口(对象发送方,RoutedEventArgs e)
{
故事板s=(故事板)TryFindResource(“sb”);
s、 Begin();//开始动画
等待任务。运行(()=>EXCEL.Analogize(路径、此、颜色));
Close();
}
public void UpdateWindow(字符串文本,整数百分比)
{
Dispatcher.Invoke(()=>
{
进度\标签内容=文本;
进度值=百分比;
});
}
}
在我的EXCEL.Analogize中,我使用gui_loading.UpdateWindow(文本,百分比)


它正在工作,但如果我尝试对windows类执行相同的操作,它将不再更新。

可能在GUI_2 UI任务中忙于加载,并且仅在完成时显示。尝试将更新放在其他任务上,并将其与UI同步

在GUI_2中

编辑:

 public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            _SyncContext = SynchronizationContext.Current;
            UpdateLabel();
        }
        SynchronizationContext _SyncContext = null;
        private async void UpdateLabel()
        {
            await Task.Run(() =>
            {
                for (int i = 1; i < 11; i++)
                {
                    Load(i);
                    Thread.Sleep(1000);
                }
            });

        }

        private void Load(int i)
        {
            SendOrPostCallback updateUI = new SendOrPostCallback(arg =>
            {
                yourLabelName.Content = $"{i}/10";
            });

            _SyncContext.Send(updateUI, null);
        }
    }
这个我测试过,它对我有效

编辑2 是的,这是可能的 一种方法是直接在构造函数中传递参数 如
Window1(字符串文本)调用该窗口时,传递参数
Window1(text)
第二种方法是(我更喜欢这种方法)创建接口(类似IWindow的东西)并在其中放入简单的加载方法
像这样

public interface IWindow
    {
       void Load(string text);
    }

public partial class Window1 : Window , IWindow
    {
//here you implement Load(string text) method.
然后你通过一些DI传递IWindow im主窗口构造函数来解析它(Autofac,Unity) 在主窗口中,您可以实例化如下内容:

//主窗口构造函数

MainWindow(IWindow iWindow)
{
_iWindow = iWindow;
}
public IWindow _iWindow { get; private set; }
并在主窗口中具有Load()方法

public void Load()
        {
            _iWindow.Load(textToPassAsParameter);
//this will call Load method from Window1
        }
private bool _isBusy;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (_isBusy != value)
                {
                    _isBusy = value;
                    OnPropertyChanged();
                }
            }
        }
要调用该加载方法,可以在xaml中进行 添加名称空间

 xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions">
并从MainWindo调用Load方法(将从Window1调用Load)

包围

<extToolkit:BusyIndicator Grid.Row="1"
                                  BusyContent="Loading..."
                                  IsBusy="{Binding IsBusy}">

<!-- your loading area -->
在加载方法中更新该get

private void Load()
        {
            IsBusy = true;
            // some load logic
            //{
            // IsBusy=false;
            //}
        }
然后在MainWindow构造函数中调用该加载方法。这样,您就不需要Window1,因为该工具包将作为子工具放置在主窗口中,并作为进度条工作。
其中,如果您在
BusyContent=“这是xceed进度条…”
中写入,您将像这样从xceed获得子加载窗口。

考虑只使用一个窗口,您可以将加载屏幕显示为主窗口根网格的子级。您尝试过但不起作用的代码是什么?我在第一个主题中尝试了一篇帖子,或者在第二个GUI的方法中放置dispatcher.invoke。为什么我会获得否决票?我尝试过,但windows只有在计数结束后才完成加载。sry,尚未测试它。现在我进行了测试,就像你说的,所以我做了一些修改,在这种情况下效果很好。window1.xaml只是一个显示用途的标签。像这样,我做了线。睡眠(1000)因为它运行到10这么快,这只是为了让它显示它如何计数。这几乎是我喜欢的!计数器在windows1中,是否可以从第一个窗口使用gui.UpdateLabel(“文本”)之类的内容进行更新?我有两种更新方法,可以传递参数。我不确定它是否足够清晰,但用简单的代码解释这个主题并不容易。我尽我所能把它说清楚。
<extToolkit:BusyIndicator Grid.Row="1"
                                  BusyContent="Loading..."
                                  IsBusy="{Binding IsBusy}">

<!-- your loading area -->
private bool _isBusy;
        public bool IsBusy
        {
            get { return _isBusy; }
            set
            {
                if (_isBusy != value)
                {
                    _isBusy = value;
                    OnPropertyChanged();
                }
            }
        }
private void Load()
        {
            IsBusy = true;
            // some load logic
            //{
            // IsBusy=false;
            //}
        }