XAML:如何仅在设计模式下更改背景颜色?

9

我有一个文本前景色为白色,背景色为透明的控件。

之后这个用户控件将被添加到带有实际背景颜色的不同控件中。

然而,在设计过程中,由于VS 2010中的白色前景和白色背景,我无法看到任何东西。是否有任何方法只在设计时定义不同的颜色?

我已经尝试过这个:

if (System.ComponentModel.DesignerProperties.IsInDesignTool)
{
    LayoutRoot.Background = new SolidColorBrush(Colors.Blue);
}

但是这并不起作用。有什么提示吗?
更新:
我不明白这对你们如何起作用。我创建了一个新的Silverlight 4.0应用程序,并将这行代码插入到构造函数中:
public MainPage()
        {
            InitializeComponent();
            LayoutRoot.Background = new SolidColorBrush(Colors.Blue);

        }

<UserControl x:Class="SilverlightApplication3.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot">

    </Grid>
</UserControl>

当我进入设计师时,我仍然没有看到它是蓝色的。并且我甚至没有任何isInDesignTime条件。我在这里缺少什么?
谢谢, Kave

你在哪里调用了上面的代码? - Andrei Pana
Andrei,在 InitializeComponent() 之后我在 ctor 中调用了它。 - Houman
最佳方法是按照这个答案中所描述的方式设置d:DesignStyle属性。 - Shahin Dohan
https://dev59.com/m1wY5IYBdhLWcg3wNFhY#32874861 ftw很高兴能够回答您的问题。在这里,“ftw”是“for the win”的缩写,表示某个事物非常好或成功。在编程中,它通常用来表达对某个代码实现或解决方案的肯定。希望对您有所帮助! - CAD bloke
6个回答

3
这里有一种方法:
if (System.ComponentModel.DesignerProperties.IsInDesignTool)
{
    LayoutRoot.Background = new SolidColorBrush(Colors.Yellow);
}

如果您转而创建一个模板化控件,您需要在OnApplyTemplate中等待设置事项,就像这个例子一样:

public override void OnApplyTemplate()
{
    base.OnApplyTemplate();
    Border b = this.GetTemplateChild("backBorder") as Border;
    if (b != null && System.ComponentModel.DesignerProperties.IsInDesignTool)
    {
        b.Background = new SolidColorBrush(Colors.Orange);
    }
}

假设这是模板:
<Style TargetType="local:TemplatedControl1">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:TemplatedControl1">
                <Border x:Name="backBorder"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我也喜欢在这样的代码周围添加条件编译指令,因为它只针对开发人员/设计师,从不需要在运行时执行。

#if DEBUG
if (System.ComponentModel.DesignerProperties.IsInDesignTool)
{
    LayoutRoot.Background = new SolidColorBrush(Colors.Yellow);
}
#endif

请注意,这种技术只有在您正在创建的UserControl在设计时被用于*另一个*UserControl/Control中才能起作用。因此,如果我建议的代码放置在名为UserControlWithDesignModeUserControl中,则您必须拥有另一个UserControl- UserControlHost,其中包含UserControlWithDesignMode控件的实例,以查看在设计时工作的行为。当前编辑的控件的代码后台只在它被包含在另一个宿主中(例如在Silverlight中,另一个UserControl)时才执行,而不是在你编辑它时执行。

感谢您的回复。请问您能否阅读我在帖子中的更新内容?非常感谢您的帮助。 - Houman
添加了一份更新(最后一段),以帮助解决我认为正在发生的事情。当前编辑的 UserControl 的代码在设计时不执行。如果控件未包含在第二个控件中,您只在代码后台中设置“Blue”,则永远不会看到它起作用。 - WiredPrairie

1
一种选择是给UserControl设置一个背景颜色,然后在使用它的地方覆盖它。这样当你单独编辑UserControl时,它会有一个背景颜色;但当你编辑包含该UserControl的控件时,你会看到透明背景,就像你想要的那样。
因此,UserControl的XAML文件应该如下所示:
<UserControl x:Class="MyUserControl" ... Background="DarkBlue">

然后在其他使用它的屏幕上,你可以这样做:

<my:MyUserControl Background="Transparent" ...>

不太优雅,但很简单。


1

不涉及代码的备选方法:

安装“Visual Studio 2012 Color Theme Editor”,下载链接在这里: http://visualstudiogallery.msdn.microsoft.com/366ad100-0003-4c9a-81a8-337d4e7ace05 创建一个基于您想要修改的主题的新自定义主题。 单击主题编辑器左上角的“显示所有元素”过滤按钮。 在主题编辑器右上角的搜索框中键入“artboard”。 将“Cider->ArtboardBackground”颜色设置为您选择的其他颜色。 太棒了! :D
注意:"Cider -> ArtboardBackground" 颜色主题字段在 VS2012 中可以找到,但我无法确认它在 VS2010 中是否具有相同的名称。

0

好的主题,特别是在做一些MVVM时,当UserControl透明时它们出现在白色背景上确实非常烦人。

我相信你可以在Blend中使用一个基于设计师是否运行的状态来解决这个问题,但我认为这并不能减少工作量。

仍然不确定如何避免在代码后台中编写代码,并且避免打开Blend,如果有人有建议,请提前感谢您的留言。

我建议使用Opacity。

<my:MyUserControl Background="Transparent" ...>

这样做是行不通的,因为它会使用户控件内部的任何子控件在运行时都变得不可见。

一个选项是给UserControl设置背景颜色,然后在使用它的地方覆盖它。

你试过在UserControl上设置背景吗?不确定为什么,但对我来说它不起作用。

有效的方法是设置Content的背景,像这样:

<UserControl x:Class="...">
<StackPanel Background="{StaticResource PhoneChromeBrush}">
...

然后将以下代码放置在视图的构造函数中

public View() {
    InitializeComponent();

    var c = Content as Panel;
    if (c != null) c.Background = new SolidColorBrush(Colors.Transparent);
}

0

您可以在UserControl构造函数中使用以下代码:

对于WPF

if (LicenseManager.UsageMode == LicenseUsageMode.Designtime)
{
    LayoutRoot.Background = new SolidColorBrush( Colors.Blue );
} 

对于 WPF / Silverlight

if (DesignerProperties.GetIsInDesignMode( this ))
{
    LayoutRoot.Background = new SolidColorBrush( Colors.Blue );
}

这个能兼容Silverlight吗?抱歉,我应该说它是Silverlight 4.0。 - Houman
非常感谢。但是从实际用户控件的设计器视图中仍然无法正常工作。但是一旦我在设计器模式下打开包含此视图的父视图,我可以看到蓝色颜色覆盖了实际颜色。为什么子设计时代码没有受到影响? - Houman
由于您正在更改背景颜色,因此我认为您需要在其他控件中实现相同的行为。如果您只需要隐藏控件(这只是一个想法),我建议使用不透明度。 - ShahidAzim

0

在这个 SO 问题中提到的另一种技术是使用未记录的属性 d:Design­er­Proper­ties.DesignStyle,它非常适用于将设计时样式应用于单个控件,但似乎无法对应用于字典范围内所有相应类型的控件或元素的ResourceDictionary中的Style进行操作。

为了解决这个问题,在同一页上我提供了一个简单的解决方案,以部署仅设计者可见的样式到ResourceDictionary中。以下是该答案的摘要:


首先,按照正常方式将所需的样式放入XAML字典中。

<Window.Resources>
    <Style TargetType="TreeViewItem">
        <Setter Property="IsExpanded" Value="True" />
    </Style>
</Window.Resources>

然后,在 C# 代码中,当检测到设计模式时,Resource­Dict­ionary中删除样式。在OnInitialized重写中执行此操作:
protected override void OnInitialized(EventArgs e)
{
    if (DesignerProperties.GetIsInDesignMode(this) == false)
        Resources.Remove(typeof(TreeViewItem));

    base.OnInitialized(e);
}

设计模式:                                                        运行时模式:

design mode    runtime mode


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接