如何知道窗口控件样式何时完成

时间:2015-07-19 21:16:49

标签: c# .net wpf

我有一个window.xaml,其组件具有不同类型的样式(边框颜色为红色,不透明度已更改等)。有一刻我想创建一个截图并保存到文件夹。但在此之前,窗口背景应该是透明的,someCanvas应该隐藏。

我怎么知道造型方法何时完成所以我可以截取屏幕截图?

public void SomeMethod()
{
    ChangeWindowControlStyles();

    //TODO: waint till 'ChangeWindowControlStyles' finished

    TageScreenshotAndSave();
}

public void ChangeWindowControlStyles()
{
     this.Background.Opacity = 0;

     this.someCanvas.Visibility = Visibility.Collapsed;

     //Some other stuff related to window content styling
}

public void TakeScreenshotAndSave()
{
    //No multithreading happening here

    //Just taking screenshot and saving to folder
}

修改

窗口本身是透明的WindowStyle="None",这意味着它没有边框。在开始时,窗口Background.Opacity设置为0.1并且所有控件都可见(除了someCanvas之外还有其他控件应始终可见)。

在截屏之前,someCanvas被隐藏,Background.Opacity设置为0。

Window.xaml

<Window
    WindowStartupLocation="CenterScreen" 
    ResizeMode="NoResize" 
    WindowState="Maximized"
    WindowStyle="None" 
    AllowsTransparency="True" >

   <Window.Background>
        <SolidColorBrush Opacity="0.1" Color="White"/>
    </Window.Background>

        <Grid Name="mainGrid" Background="Transparent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0">

            <!--Main canvas, function holder-->
            <Canvas Name="canvasAlwaysVisible" Margin="0" Panel.ZIndex="5">
                <!-- Controls that are always visible -->
            </Canvas>

            <Canvas x:Name="someCanvas" Margin="0" Background="Transparent" Visibility="Visibility">
                <!-- Controls with styling -->
            </Canvas>

        </Grid>
</Window>

编辑2

另外要提到的是,TakeScreenshotAndSave内部还有System.IO个操作,例如 - 获取目录中的所有文件夹,创建新目录等等。也许.NET看到了它并且它是异步运行的。

1 个答案:

答案 0 :(得分:0)

看起来我找到了解决方案。我不知道它为什么会起作用,需要调查更多。我在代码示例中提到的TakeScreenshotAndSave方法以某种方式在不同的线程上运行。在Application.Current.Dispatcher内包装该方法时,它有效!

public void SomeMethod()
{
    ChangeWindowControlStyles();

    var m_dispatcher = Application.Current.Dispatcher;

    m_dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle,
    new System.Threading.ThreadStart(delegate
    {

        TakeScreenshotAndSave(); //Now running on UI thread

    }));
}