不幸的是,我必须在与主应用程序不同的线程上触发此窗口。然后我每次在MakeWindow类中更改字符串输入_html时都尝试更新它。
现在我收到错误,说我无法执行此操作,因为我是从创建它的其他线程调用它。我怎样才能在这里工作?
有没有办法在窗口存在的同一个线程上实现该事件监听器?请记住,_html将始终在主线程上设置和更新。想法?
谢谢!
我的班级:
namespace Windamow
{
public static class WebBrowserUtility
{
public static readonly DependencyProperty BindableSourceProperty =
DependencyProperty.RegisterAttached("BindableSource", typeof(string),
typeof(WebBrowserUtility), new UIPropertyMetadata(null,
BindableSourcePropertyChanged));
public static string GetBindableSource(DependencyObject obj)
{
return (string)obj.GetValue(BindableSourceProperty);
}
public static void SetBindableSource(DependencyObject obj, string value)
{
obj.SetValue(BindableSourceProperty, value);
}
public static void BindableSourcePropertyChanged(DependencyObject o,
DependencyPropertyChangedEventArgs e)
{
var webBrowser = (WebBrowser)o;
webBrowser.NavigateToString((string)e.NewValue);
}
}
public class Windamow
{
private DynamoWindow window;
public static string html;
internal void ThreadProc()
{
string appName = "";
try
{
appName = Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location);
const string IE_EMULATION = @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
using (var fbeKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(IE_EMULATION, true))
{
fbeKey.SetValue(appName, 9000, Microsoft.Win32.RegistryValueKind.DWord);
}
}
catch (Exception ex)
{
MessageBox.Show(appName + "\n" + ex.ToString(), "Unexpected error setting browser mode!");
}
window = new DynamoWindow();
window.ShowDialog();
}
internal Windamow()
{
Thread t = new Thread(ThreadProc);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
/// <summary>
/// asd
/// </summary>
/// <param name="launch"></param>
/// <param name="_html"></param>
/// <returns></returns>
public static DynamoWindow MakeWindow(bool launch, string _html)
{
if (launch)
{
if (MyProject.Utility.WebBrowserUtility.IsWindowOpen<Window>("MainWindow"))
{
html = _html;
return null;
}
else
{
html = _html;
Windamow mow = new Windamow();
return mow.window;
}
}
else
{
return null;
}
}
}
}
XAML:
<Window x:Class="Windamow.DynamoWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
xmlns:ns="clr-namespace:Windamow"
Title="MainWindow"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<!--<WebBrowser x:Name="browser" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>-->
<WebBrowser x:Name="browser" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ns:WebBrowserUtility.BindableSource="{Binding ReportPage}"/>
</Grid>
xaml.cs:
namespace Windamow
{
/// <summary>
/// Interaction logic for DynamoWindow.xaml
/// </summary>
public partial class DynamoWindow : Window
{
public DynamoWindow()
{
InitializeComponent();
}
}
}
答案 0 :(得分:1)
我上传了一个样本,提取并运行: Browser
它还包含WinA,WinB窗口。您可以通过在App.xaml中更改来运行WinA。并了解WinA如何访问/设置WinB控件/属性。
我更改了您的MakeWindow功能。
我为您的DynamoWindow代码隐藏做了一些补充。
主窗口
<Window x:Class="Windamow.Win32803621"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Win32803621" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="42*"/>
<RowDefinition Height="79*"/>
<RowDefinition Height="149*"/>
</Grid.RowDefinitions>
<Button x:Name="btnCreateAndOpen" Content="Create browser on new thread" HorizontalAlignment="Left" Margin="67,10,0,0" VerticalAlignment="Top" Click="btnCreateAndOpen_Click"/>
<TextBox x:Name="tbHtmlInput" HorizontalAlignment="Left" Height="59" Margin="10,10,0,0" Grid.Row="1" TextWrapping="Wrap" VerticalAlignment="Top" Width="272" AcceptsReturn="True" AcceptsTab="True"/>
<Button x:Name="btnUpdateBrowser" Content="Update browser" HorizontalAlignment="Left" Margin="88,10,0,0" Grid.Row="2" VerticalAlignment="Top" Width="98" Click="btnUpdateBrowser_Click"/>
</Grid>
</Window>
MainWindow代码隐藏
using System;
using System.Windows;
using System.Windows.Controls;
namespace Windamow
{
/// <summary>
/// Interaction logic for Win32803621.xaml
/// </summary>
public partial class Win32803621 : Window
{
public Win32803621()
{
InitializeComponent();
tbHtmlInput.Text = "<a href='http://www.stackoverflow.com'>Click to open StackOverflow.com</a>";
}
DynamoWindow browserWindow;
private void btnCreateAndOpen_Click(object sender, RoutedEventArgs e)
{
Windamow.MakeWindow(true, tbHtmlInput.Text);
}
private void btnUpdateBrowser_Click(object sender, RoutedEventArgs e)
{
browserWindow = Windamow.window;
browserWindow.ReportPage = tbHtmlInput.Text;
}
}
}
创建线程/窗口的助手类
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Threading;
using System.IO;
namespace Windamow
{
public static class WebBrowserUtility
{
public static readonly DependencyProperty BindableSourceProperty =
DependencyProperty.RegisterAttached("BindableSource", typeof(string),
typeof(WebBrowserUtility), new UIPropertyMetadata(null,
BindableSourcePropertyChanged));
public static string GetBindableSource(DependencyObject obj)
{
return (string)obj.GetValue(BindableSourceProperty);
}
public static void SetBindableSource(DependencyObject obj, string value)
{
obj.SetValue(BindableSourceProperty, value);
}
public static void BindableSourcePropertyChanged(DependencyObject o,
DependencyPropertyChangedEventArgs e)
{
WebBrowser webBrowser = (WebBrowser)o;
webBrowser.NavigateToString((string)e.NewValue);
}
}
public class Windamow
{
public static DynamoWindow window;
public static string html;
internal void ThreadProc()
{
string appName = "";
try
{
appName = Path.GetFileName(System.Reflection.Assembly.GetEntryAssembly().Location);
const string IE_EMULATION = @"Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_BROWSER_EMULATION";
using (var fbeKey = Microsoft.Win32.Registry.CurrentUser.OpenSubKey(IE_EMULATION, true))
{
fbeKey.SetValue(appName, 9000, Microsoft.Win32.RegistryValueKind.DWord);
}
}
catch (Exception ex)
{
MessageBox.Show(appName + "\n" + ex.ToString(), "Unexpected error setting browser mode!");
}
window = new DynamoWindow();
window.ShowDialog();
}
internal Windamow()
{
Thread t = new Thread(ThreadProc);
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
/// <summary>
/// asd
/// </summary>
/// <param name="launch"></param>
/// <param name="_html"></param>
/// <returns></returns>
public static void MakeWindow(bool launch, string _html)
{
Windamow mow = new Windamow();
//return mow.window;
//if (launch)
//{
// if (MyProject.Utility.WebBrowserUtility.IsWindowOpen<Window>("MainWindow"))
// {
// html = _html;
// return null;
// }
// else
// {
// html = _html;
// Windamow mow = new Windamow();
// return mow.window;
// }
//}
//else
//{
// return null;
//}
}
}
}
DynamoWindow代码隐藏类:
namespace Windamow
{
/// <summary>
/// Interaction logic for DynamoWindow.xaml
/// </summary>
public partial class DynamoWindow : Window, INotifyPropertyChanged
{
private String _reportPage;
public String ReportPage { get { return _reportPage; } set { _reportPage = value; OnPropertyChanged("ReportPage"); } }
public DynamoWindow()
{
InitializeComponent();
browser.DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(String propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
}
}