我有一个这样定义的附加行为,..
public static class FileBrowserBehaviour
{
public static bool GetBrowsesOnClick(DependencyObject obj)
{
return (bool)obj.GetValue(BrowsesOnClickProperty);
}
public static void SetBrowsesOnClick(DependencyObject obj, bool value)
{
obj.SetValue(BrowsesOnClickProperty, value);
}
// Using a DependencyProperty as the backing store for BrowsesOnClick. This enables animation, styling, binding, etc...
public static readonly DependencyProperty BrowsesOnClickProperty =
DependencyProperty.RegisterAttached("BrowsesOnClick", typeof(bool), typeof(FileBrowserBehaviour), new FrameworkPropertyMetadata(false, new PropertyChangedCallback(BrowsesOnClickChanged)));
public static void BrowsesOnClickChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
FrameworkElement fe = obj as FrameworkElement;
if ((bool)args.NewValue)
{
fe.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(OpenFileBrowser);
}
else
{
fe.PreviewMouseLeftButtonDown -= new MouseButtonEventHandler(OpenFileBrowser);
}
}
static void OpenFileBrowser(object sender, MouseButtonEventArgs e)
{
var tb = sender as TextBox;
if (tb.Text.Length < 1 || tb.Text=="Click to browse..")
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "Executables | *.exe";
if (ofd.ShowDialog() == true)
{
Debug.WriteLine("Setting textbox text-" + ofd.FileName);
tb.Text = ofd.FileName;
Debug.WriteLine("Set textbox text");
}
}
}
}
这是一个很好的简单附加行为,当您单击文本框时会弹出打开 OpenFileDialog 并在完成后将文件名放入框中。
它可能在 40% 的时间内工作,但其余时间整个应用程序都会挂起。此时的调用堆栈如下所示 -
[Managed to Native Transition]
WindowsBase.dll!MS.Win32.UnsafeNativeMethods.GetMessageW(ref System.Windows.Interop.MSG msg, System.Runtime.InteropServices.HandleRef hWnd, int uMsgFilterMin, int uMsgFilterMax) + 0x15 bytes
WindowsBase.dll!System.Windows.Threading。 Dispatcher.GetMessage(参考 System.Windows.Interop.MSG msg,System.IntPtr hwnd,int minMessage,int maxMessage)+ 0x48 字节 WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame 帧= {System.Windows.Threading.DispatcherFrame}) + 0x8b 字节 WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrame(System.Windows.Threading.DispatcherFrame 帧) + 0x49 字节
WindowsBase.dll!System.Windows.Threading。 Dispatcher.Run() + 0x4c 字节
PresentationFramework.dll!System.Windows.Application.RunDispatcher(对象忽略) + 0x1e 字节
PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window 窗口) + 0x6f 字节 PresentationFramework.dll!System.Windows.Application。 Run(System.Windows.Window window) + 0x26 bytes PresentationFramework.dll!System.Windows.Application.Run() + 0x19 bytes Debugatron.exe!Debugatron.App.Main() + 0x5e bytes C# [Native to Managed Transition]
[管理到本地转换]
mscorlib.dll!System.AppDomain.nExecuteAssembly(System.Reflection.Assembly 程序集,string[] args) + 0x19 字节 mscorlib.dll!System.Runtime.Hosting.ManifestRunner.Run(bool checkAptModel) + 0x6e 字节 mscorlib.dll!System .Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() + 0x84 字节 mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext, string[] activationCustomData) + 0x65 字节 mscorlib.dll!System.Runtime.Hosting。 ApplicationActivator.CreateInstance(System.ActivationContext activationContext) + 0xa 字节 mscorlib.dll!System.Activator.CreateInstance(System.ActivationContext activationContext) + 0x3e 字节
Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() + 0x23 字节
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(对象状态) + 0x66 字节
mscorlib.dll!System.Threading。 ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback 回调, 对象状态) + 0x6f 字节
mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 字节
现在,我以前在做一些异步事情时见过这种事情,但那时还没有发生。唯一活着的线程是 UI 线程!此外,当它挂起时,我总是得到最后一个调试语句。
谁能指出我正确的方向?这个快把我逼疯了!