Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.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# 从类编辑主窗口上的列表框_C#_Wpf_Reference - Fatal编程技术网

C# 从类编辑主窗口上的列表框

C# 从类编辑主窗口上的列表框,c#,wpf,reference,C#,Wpf,Reference,我有一个WPF应用程序,我创建了一个名为Agent的新类。在我的WPF应用程序窗口中,我有列表框。我从MainWIndow.xaml.cs调用Agent 代理类运行一个FileSystemWatcher,现在当引发OnChanged事件时,我想将消息添加到列表框中,说明该事件已引发 MainWindow.xaml 在MainWindow.xaml.cs中,我有: Agent agent = null; private void runAgent_Click(object

我有一个WPF应用程序,我创建了一个名为
Agent
的新类。在我的WPF应用程序窗口中,我有
列表框
。我从MainWIndow.xaml.cs调用
Agent

代理类运行一个
FileSystemWatcher
,现在当引发
OnChanged
事件时,我想将消息添加到
列表框
中,说明该事件已引发

MainWindow.xaml


在MainWindow.xaml.cs中,我有:

    Agent agent = null;

    private void runAgent_Click(object sender, RoutedEventArgs e)
    {
        if (agent == null || !agent._running)
        {
            agent = new Agent(@"W:\MindWare.SVN\CardMax2\trunk\ProcessEngine\TSPHelper.Producer\bin\Debug\GeneratedLogs");
            runAgent.Content = "Stop Agent";
        }
        else if (agent._running)
        {
            agent.StopAgent();
            runAgent.Content = "Run Agent";
        }
    }
和代理级别:

public class Agent
{
    private string Path { get; set; }
    public bool _running { get; set; }

    FileSystemWatcher watcher = new FileSystemWatcher();

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public Agent(string path)
    {
        Path = path;
        watcher.Path = path;
        watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
           | NotifyFilters.FileName | NotifyFilters.DirectoryName;
        watcher.Filter = "*.txt";
        watcher.IncludeSubdirectories = true;

        watcher.Changed += new FileSystemEventHandler(OnChanged);

        watcher.EnableRaisingEvents = true;
        _running = true;
    }

    // Stop Agent
    public void StopAgent()
    {
        watcher.EnableRaisingEvents = false;
        _running = false;
    }

    // Define the event handlers.
    private void OnChanged(object source, FileSystemEventArgs e)
    {        
        try
        {
            watcher.EnableRaisingEvents = false;
            _running = false;

            // DO SOMETHING HERE
            // Add item to ListBox on MainWindow somehow
        }
        finally
        {
            watcher.EnableRaisingEvents = true;
            _running = true;
        }
    }
public class Agent
{
public static MainWindow mainWindow;

....
}

我怎么能做到这一点呢?

您可能不应该这样做,因为模型类应该独立于视图

除此之外,为什么不将引用传递给类的构造函数或将ListView字段公开为公共或内部属性


要公开列表框,请创建如下属性:

public ListBox MessageBox { get { return messageBox; } }

这应该在您的主窗口代码中,然后您可以通过
MainWindow.MessageBox

访问窗口任何实例上的列表框。我想我理解您的意思

您可以在代理类中创建静态MainWindow对象:

public class Agent
{
    private string Path { get; set; }
    public bool _running { get; set; }

    FileSystemWatcher watcher = new FileSystemWatcher();

    [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
    public Agent(string path)
    {
        Path = path;
        watcher.Path = path;
        watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
           | NotifyFilters.FileName | NotifyFilters.DirectoryName;
        watcher.Filter = "*.txt";
        watcher.IncludeSubdirectories = true;

        watcher.Changed += new FileSystemEventHandler(OnChanged);

        watcher.EnableRaisingEvents = true;
        _running = true;
    }

    // Stop Agent
    public void StopAgent()
    {
        watcher.EnableRaisingEvents = false;
        _running = false;
    }

    // Define the event handlers.
    private void OnChanged(object source, FileSystemEventArgs e)
    {        
        try
        {
            watcher.EnableRaisingEvents = false;
            _running = false;

            // DO SOMETHING HERE
            // Add item to ListBox on MainWindow somehow
        }
        finally
        {
            watcher.EnableRaisingEvents = true;
            _running = true;
        }
    }
public class Agent
{
public static MainWindow mainWindow;

....
}
然后在MainWindow.cs中,您可以将窗口添加到变量中

private void Window_Loaded(object sender, RoutedEventArgs e)
{
  Agent.mainWindow = this;
  ....
}
现在,当您需要访问此窗口时,可以参考mainWindow:

public class Agent
{
public static MainWindow mainWindow;

public void AddToList(string value)
{
   mainWindow.listBox1.items.add(value);
}
编辑:线程错误的更新

听起来像FileSystemWatcher在UI的一个单独线程上运行。您可以通过将工作传递给UI线程来管理这一点

// DO SOMETHING HERE
// Add item to ListBox on MainWindow somehow
if (!mainWindow.Dispatcher.CheckAccess())
    {
       mainWindow.Dispatcher.BeginInvoke(
           System.Windows.Threading.DispatcherPriority.Normal,
           new Action(
              delegate()
              {
               //Code to make changes to the mainWindow if the thread does not have access:
                mainWindow.listBox1.Items.Add("hello");                                
              }));
    }
    else
    {
        //Access allowed make changes normally.
        mainWindow.listBox1.Items.Add("hello");
    }

Martyn

想给我们你目前所拥有的吗?我猜大多数人都不想为您键入整个程序,但我们可以帮助您填补空白。如何将我的列表框公开?当然,您仍然需要对窗口实例的引用,除非您使用静态属性,我不推荐使用静态属性。(在
App
类中已经有了一个属性,只需在创建主窗口时设置它,然后就可以通过
(Application.Current.MainWindow作为MainWindow)从任何地方访问列表框。MessageBox
)无法真正做到这一点。获取错误:
调用线程无法访问此对象,因为另一个线程拥有它。
请查看,对于来自不同线程的UIElements调用,您需要使用Dispatcher。(您可能应该通过@hs2d执行此操作)@hs2d我在上面添加了一些代码,允许您从不同的线程更改列表框。