C# 从类编辑主窗口上的列表框
我有一个WPF应用程序,我创建了一个名为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
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我在上面添加了一些代码,允许您从不同的线程更改列表框。