2011-02-15 86 views
2

我有一个包含TextBox,ToggleButton和Popup的用户控件,就像真正的ComboBox一样。现在我的问题是,它的样式,使它看起来就像普通的组合框。如何让我的UserControl看起来像一个ComboBox?

在Blend中,我可以通过“编辑模板/编辑副本......”一个真正的组合框来获取我需要得到它看的权利的点点滴滴。对于一个Windows主题(Aero)。如果应用程序在另一个主题(例如Luna)上运行,控件不会改变其外观,它仍然具有Aero外观。

我必须提供一个风格/模板每个Windows主题,或者我可以以某种方式得到保持(在运行时),默认的组合框样式,并将其应用到我的用户?

而不是使一个用户控件,我已经尝试修改一个真正的ComboBox我的需求,但我无法得到它的工作。我怎样才能用我自己的所有组合框的逻辑?

+0

对于初学者,你在说什么逻辑?你的控件与一个使ComboBox不够用的ComboBox不同? – 2011-03-20 15:28:58

回答

1

利用Windows主题将是解决这个问题的方法之一。大部分内容都是从Adam Nathan的Windows Presentation Foundation Unleashed中解释和截断的。

简单方法

你可以用在你的控制模板,通过SystemColorsSystemFontsSystemParameters暴露的资源和按键(连同DynamicResource,如果主题是你的程序运行时改变)来设置适当的值:

Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" 

可靠的方法

更好的方法是,虽然需要更多的工作,但每个主题都有一个控制模板,而不是一个覆盖所有内容的控件模板。您这样做的方式是将所有主题特定资源放入其自己的资源字典中。这些字典放置在项目根目录的主题子文件夹中,并且每个字母均以主题名称和主题颜色命名:ThemeName.ThemeColor.xaml。

请注意,您仍然使用SystemColors,SystemFontsSystemParameters,就像在简单的方法中一样。

我没有这本书,可能列出的Windows 7主题的更新版,但这里是那些亚当在编辑我列出:

  • Vista的Aero:主题\ Aero.NormalColor。 XAML
  • XP默认:主题\ Luna.NormalColor.xaml
  • XP绿色:主题\ Luna.Homestead.xaml
  • XP银:主题\ Luna.Metallic.xaml
  • XP大逃杀:主题\皇家。 NormalColor.xaml
  • XP的Zune:主题\ Zune.NormalColor.xaml
  • 经典:主题\ Classic.xaml

这些将被自动加载,并切换出主题是否会发生变化。您也可以指定themes \ Generic。当xaml尝试加载没有创建资源字典以匹配的主题时,将其作为默认值。

您还可以选择加入自动主题化与ThemeInfoAttribute

//look inside this assembly 
[assembly:ThemeInfo(ResourceDictionaryLocation.SourceAssembly, 
    ResourceDictionaryLocation.SourceAssembly)] 

ResourceDictionaryLocation也有一个ExternalAssembly选项。这些外部程序集的命名约定是MainAssembly.ThemeName.dll,因此如果程序集名为MyApp,它将在MyApp.Classic.dll中查找经典主题资源字典。

最后,您使用ThemeDictionaryExtension在你的应用程序资源词典:

<Application.Resources> 
    <ResourceDictionary> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="{ThemeDictionary MyApp}"/> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary> 
</Application.Resources> 

如果您从另一个控件派生(不UserControl,但ProgressBar,例如)的自定义控件,你应该这样做它的静态构造函数如下:

DefaultStyleKeyProperty.OverrideMetadata(typeof(MyControl), 
    new FrameworkPropertyMetadata(typeof(MyControl))); 
相关问题