【问题标题】:How to show a WPF window from Class Library (dll) project?如何从类库(dll)项目中显示 WPF 窗口?
【发布时间】:2018-09-14 15:59:51
【问题描述】:

我最近为我的其他项目制作了一个类库 (dll),以通过串行端口 (COM) 对蓝牙设备进行编程。该库用于通过 COM 端口传输固件。在需求到来之前它工作正常,这需要一个 WPF 窗口来显示编程进度。我已经使用标准 WPF 应用程序模板成功创建了进度条。但是,标准的 WPF 不允许我生成 dll。在这里搜索后,我找到了这个link,它教你如何将WPF窗口添加到现有的类库项目中。另外,有人教你如何从here 显示窗口。在我尝试之前一切看起来都很好,当我从 LabVIEW 调用方法 ProgrammBluetooth() 时没有任何显示。

我的主要方法,在一个单独的 .cs 文件中:

namespace BTMProg
{
public class BTMProgrammer
{
    private bool _uut1Status = false;
    private string _uut1Message = "";

    public bool UUT1Status
    {
        get { return _uut1Status; }
        set { _uut1Status = value; }
    }

    public string UUT1Message
    {
        get { return _uut1Message; }
        set { _uut1Message = value; }
    }

    public void ProgramBluetooth (string ioPort, string firmwareFile)
    {
        List<UUT> uutList = new List<UUT>(); 
        uutList.Add(new UUT(ioPort, "UUT1", 1));

        Thread thread = new Thread(() =>
        {
            var wn = new MainWindow(uutList, firmwareFile);
            wn.ShowDialog();
            wn.Closed += (s, e) => wn.Dispatcher.InvokeShutdown();
            Dispatcher.Run();
            if (wn.TaskList[0].Result.ToUpper().Contains("SUCCESS"))
            {
                _uut1Status = true;
                _uut1Message = wn.TaskList[0].Result;
            }
            else
            {
                _uut1Status = false;
                _uut1Message = wn.TaskList[0].Result;
            }
        });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }
}
}

我在 MainWindow.xaml.cs 中的 WPF 代码:

 ProgrammingViewModel _pvm = new ProgrammingViewModel();
 private List<string> _viewModeList = new List<string>();
 private List<Task<string>> _taskList = new List<Task<string>>();

 public List<Task<string>> TaskList {
     get => _taskList;
     set => _taskList = value;
 }

 public MainWindow(List<UUT> uutList, string firmwareFile)
 {
     InitializeComponent();
     foreach (var uut in uutList)
     {
         _viewModeList.Add(uut.UutName);
     }
     _pvm.AddProcessViewModels(_viewModeList);
     ProgressBarView.DataContext = _pvm.ProcessModels;
     StartProgramming(uutList, firmwareFile);
     Application.Current.MainWindow.Close();
  }

之前的问题是,如果我不使用调度程序创建一个新线程,则会抛出一个异常说“调用线程必须是 STA,因为许多 UI 组件都需要这个....”。使用新线程后,没有错误,但窗口没有按预期显示。可能是什么问题呢?谢谢。

【问题讨论】:

    标签: c# wpf dll


    【解决方案1】:

    ShowDialog 函数将停止线程的执行,直到窗口关闭,这意味着该代码的其余部分可能不会运行并且调度程序可能不会启动。您应该尝试使用 Show 方法,它会在窗口显示后立即返回。

    另外,窗口的构造函数中的这些行是怎么回事?

    StartProgramming(uutList, firmwareFile);
    Application.Current.MainWindow.Close();
    

    无论第一行做什么,如果您希望窗口完成构建,它需要返回而不是做大量工作。第二行根本没有意义。为什么要关闭应用程序的主窗口?您是否在某个时候设置并打开了与该属性关联的窗口?

    我怀疑其中一件或多件事情正在阻止线程到达它可以显示窗口的点。

    【讨论】:

    • 我猜这就是它不起作用的原因,构造函数没有完成那么就不会有窗口。我不知道。我会尝试修复它。谢谢。
    猜你喜欢
    • 2011-04-15
    • 1970-01-01
    • 2011-04-04
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-20
    • 1970-01-01
    相关资源
    最近更新 更多