2010-10-07 50 views
4

我的复选框没有复选标记。如果我仅使用一个复选框(实例对象)进行渲染,则可以显示复选标记,但我无法使用此解决方案。我需要能够使用本地复选框来呈现它。这个复选框通过“/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml”应用了Aero主题,这对我来说也是必须的。其他主题内置的主题,如皇家和月神呈现与复选标记。如何将选中的CheckBox(Aero主题)渲染为RenderTargetBitmap?

XAML

<Canvas Name="canvas"> 
    <Button Click="Button_Click" Canvas.Left="440" Canvas.Top="277"> 
     Do Paint 
    </Button> 
    <Image Name="image"/> 
</Canvas> 

C#

private void Button_Click(object sender, RoutedEventArgs e) { 
    var checkBox = new CheckBox { Width = 100, Height = 30, IsChecked = true, }; 
    var rectangle = new Rect(0, 0, checkBox.Width, checkBox.Height); 

    //need this 
    var visualBrush = new VisualBrush(checkBox); 
    checkBox.Arrange(rectangle); 

    var renderTargetBitmap = new RenderTargetBitmap((int)rectangle.Width, (int)rectangle.Height, 96, 96, PixelFormats.Default); 
    renderTargetBitmap.Render(checkBox); 
    renderTargetBitmap.Freeze(); 

    image.Source = renderTargetBitmap; 
} 

回答

4

我使用反射来看看PresentationFramework.Aero组装的内容,我发现了什么是怎么回事。我有一个解决方案,但你可能不会喜欢它...

在Aero主题中,复选框使用BulletChrome控件呈现。此控件在从一个状态切换到另一个状态时使用动画,因此当您复选该复选框时,从未选中到已选中的动画未完成,并且刻度标记尚不可见。所以你需要等待动画完成...

只是在渲染之前放置一个Thread.Sleep将无法​​正常工作,因为在调度程序线程处于睡眠状态时,动画将停止。所以,你需要开始一个新的线程,你渲染复选框前等待:

private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     var checkBox = new CheckBox { Width = 100, Height = 30, IsChecked = true, }; 
     var rectangle = new Rect(0, 0, checkBox.Width, checkBox.Height); 

     //need this 
     var visualBrush = new VisualBrush(checkBox); 
     checkBox.Arrange(rectangle); 

     new Thread(() => 
      { 
       Thread.Sleep(300); // the animation lasts 300ms 
       Dispatcher.Invoke(() => 
           { 
            var renderTargetBitmap = 
             new RenderTargetBitmap((int)rectangle.Width, 
                  (int)rectangle.Height, 96, 96, 
                  PixelFormats.Default); 
            renderTargetBitmap.Render(checkBox); 
            renderTargetBitmap.Freeze(); 

            image.Source = renderTargetBitmap; 
           }); 
      }).Start(); 
    } 

(此代码使用DispatcherExtensions.Invoke扩展方法,所以你需要引用System.Windows.Presentation组装和进口System.Windows.Threading命名空间)

请注意,如果SystemParameters.ClientAreaAnimation为假,则不会发生动画。但由于此属性是只读的,它并没有真正帮助你...

+1

您的解决方案没有解决我的问题,但给了我一个解释,为什么WPF的行为就像它有关CheckBox控件...谢谢 – reSPAWNed 2011-08-04 12:32:54