【问题标题】:How to render a checked CheckBox (Aero theme) to a RenderTargetBitmap?如何将选中的 CheckBox(Aero 主题)渲染到 RenderTargetBitmap?
【发布时间】:2010-10-08 05:02:23
【问题描述】:

我的复选框没有复选标记。如果我只使用一个复选框(实例对象)进行渲染,那么我可以显示复选标记,但我不能使用这个解决方案。我需要能够使用本地复选框呈现它。这个复选框通过“/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml”应用了 Aero 主题,这对我来说也是必须的。其他主题内置主题,如 Royal 和 Luna,带有复选标记。

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;
}

【问题讨论】:

    标签: wpf


    【解决方案1】:

    我使用 Reflector 查看了 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 为假,则不会出现动画。但是由于这个属性是只读的,它并不能真正帮助你......

    【讨论】:

    • 您的解决方案没有解决我的问题,但解释了为什么 WPF 的行为与 CheckBox 控件类似...谢谢
    猜你喜欢
    • 1970-01-01
    • 2015-02-11
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2015-03-31
    • 1970-01-01
    相关资源
    最近更新 更多