I have a WPF application which calls OpenFileDialog.ShowDialog. While this dialog is open it is possible and expected behavior that my applicaton alters the background and shows new information.
If the user now closes this dialog the background is restored, which means there is old information on the screen.
How can I prevent the OpenFileDialog from saving it's background?
Or if this is not possible, how can I force a repaint of my application?
Sample code, press button and position dialog over text:
<Window x:Class="BackgroundOfFileOpen.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Viewbox Grid.Row="0">
<Label Content="{Binding textInBackground}" />
</Viewbox>
<Button Grid.Row="1" Click="OnOpenDialog">Open Dialog</Button>
</Grid>
using Microsoft.Win32;
using System.Windows;
using System.Threading;
using System;
namespace BackgroundOfFileOpen
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public string textInBackground
{
get { return (string)GetValue(textInBackgroundProperty); }
set { SetValue(textInBackgroundProperty, value); }
}
// Using a DependencyProperty as the backing store for textInBackground. This enables animation, styling, binding, etc...
public static readonly DependencyProperty textInBackgroundProperty =
DependencyProperty.Register("textInBackground", typeof(string), typeof(MainWindow), new UIPropertyMetadata("Text"));
public MainWindow()
{
InitializeComponent();
DataContext = this;
function += ModifyText;
开发者_高级运维 }
private void OnOpenDialog(object sender, RoutedEventArgs e)
{
Thread backgroundThread = new Thread(ThreadMethod);
backgroundThread.Start();
OpenFileDialog dlg = new OpenFileDialog();
dlg.ShowDialog();
}
public void ModifyText()
{
if (Dispatcher.CheckAccess())
{
textInBackground += "x";
}
else
{
Dispatcher.BeginInvoke(new Action(() => { ModifyText(); }));
}
}
delegate void ModifyFunction();
static ModifyFunction function;
static void ThreadMethod()
{
Thread.Sleep(1000);
function();
}
}
}
how can I force a repaint of my application?
After closing the dialog use UIExtensions.Refresh(this);
public static class UIExtensions
{
public static void Refresh(this UIElement uiElement)
{
uiElement.Dispatcher.Invoke(DispatcherPriority.Render, new Action(() => { }));
}
}
For anyone who is interested, the only workaround I found by now is to call following function after ShowDialog. It's not nice, and it flickers, if the window is maximized, but it works on all tested systems.
void RefreshWindow()
{
switch (WindowState)
{
case WindowState.Maximized:
{
double oldWidth = Width;
Width = System.Windows.SystemParameters.PrimaryScreenWidth - 1;
WindowState = System.Windows.WindowState.Normal;
WindowState = System.Windows.WindowState.Maximized;
Width = oldWidth;
}
break;
case WindowState.Normal:
if (Width > 1)
{
Width -= 1;
Width += 1;
}
else
{
Width += 1;
Width -= 1;
}
break;
case WindowState.Minimized:
default:
// no action necessary
break;
}
}
精彩评论