如何让我的 UserControl 看起来像 ComboBox?
我有一个包含 TextBox、ToggleButton 和 Popup 的用户控件,就像真正的 ComboBox 一样。现在我的问题是设置它的样式,使其看起来像普通的 ComboBox。
在 Blend 中,我可以“编辑模板/编辑副本...”真实的 ComboBox 来获取使其看起来正确所需的零碎内容。适用于一种 Windows 主题 (Aero)。如果应用程序在另一个主题(例如 Luna)上运行,则控件不会改变其外观,它仍然具有 Aero 外观。
我是否必须为每个 Windows 主题提供样式/模板,或者我可以以某种方式获取(在运行时)默认的 ComboBox 样式并将其应用到我的 UserControl 吗?
我没有制作 UserControl,而是尝试根据我的需要修改真正的 ComboBox,但我就是无法让它工作。如何用我自己的逻辑替换 ComboBox 的所有逻辑?
I have a user control containing a TextBox, ToggleButton and Popup, just like the real ComboBox. Now my problem is to style it so that it looks just like the normal ComboBox.
In Blend, I can "Edit Template/Edit a Copy..." of a real ComboBox to get the bits and pieces I need to get it to look right. For one Windows theme (Aero). If the application is run on another theme (e.g Luna), the control does not change its look, it still has the Aero look.
Do I have to supply a style/template for each Windows theme, or can I somehow get hold of (at run-time) the default ComboBox style and apply it to my UserControl?
Instead of making a UserControl, I have tried modifying a real ComboBox to my needs, but I just couldn't get it to work. How can I replace ALL the logic of a ComboBox with my own?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
利用 Windows 主题将是解决此问题的一种方法。其中大部分内容是从 Adam Nathan 的 Windows Presentation Foundation Unleashed 中转述和删节的。
简单方法
您可以在控件模板中使用
SystemColors
、SystemFonts
和SystemParameters
公开的资源和键(与DynamicResource
(以防在程序运行时主题发生更改)一起设置适当的值:稳健方法
更好的方法是,尽管它需要更多工作每个主题都有一个控制模板,而不是一套覆盖所有内容的控制模板。执行此操作的方法是将所有特定于主题的资源放入它们自己的资源字典中。这些字典放置在项目根目录的 themes 子文件夹中,每个字典均以主题名称和主题颜色命名:ThemeName.ThemeColor.xaml。
请注意,您仍然使用
SystemColors
、SystemFonts
和SystemParameters
,如简单方法中所示。我没有可能列出 Windows 7 主题的较新版本的书,但以下是 Adam 在我拥有的版本中列出的主题:
这些将自动加载,并在主题更改时关闭。当它尝试加载您尚未创建匹配的资源字典的主题时,您还可以将主题\Generic.xaml 指定为默认值。
您还必须使用
ThemeInfoAttribute
选择自动主题:ResourceDictionaryLocation
还有一个ExternalAssembly
选项。这些外部程序集的命名约定是 MainAssembly.ThemeName.dll,因此如果您的程序集名为 MyApp,它将在 MyApp.Classic.dll 中查找经典主题资源字典。最后,您在应用程序资源字典中使用
ThemeDictionaryExtension
:如果您创建从另一个控件派生的任何自定义控件(不是
UserControl
,而是ProgressBar
) ,例如),您应该在其静态构造函数中执行此操作:Taking advantage of Windows themes would be one way to approach this. Most of this is paraphrased and truncated from Windows Presentation Foundation Unleashed by Adam Nathan.
Simple Approach
You could use the resources and keys exposed by
SystemColors
,SystemFonts
, andSystemParameters
in your control template (along withDynamicResource
, in case the theme is changed while your program is running) to set the appropriate values:Robust Approach
The better way, though it requires more work, is to have a control template for each theme rather than one set that overrides everything. The way you do this is to put all your theme-specific resources into their own resource dictionary. These dictionaries are placed in a themes subfolder in the root of your project, and are each named after the theme name and theme color: ThemeName.ThemeColor.xaml.
Note that you still use
SystemColors
,SystemFonts
, andSystemParameters
, as in the simple approach.I don't have the newer edition of the book that probably lists Windows 7 themes, but here are the ones Adam lists in the edition I have:
These will be automatically loaded, and switched out if the theme is changed. You can also specify themes\Generic.xaml as a default when it tries to load a theme that you haven't a created a resource dictionary to match.
You also have to opt-in to the automatic theming with
ThemeInfoAttribute
:ResourceDictionaryLocation
also has anExternalAssembly
option. The naming convention for these external assemblies is MainAssembly.ThemeName.dll, so if your assembly is called MyApp, it would look for the Classic theme resource dictionary in MyApp.Classic.dll.And finally, you use
ThemeDictionaryExtension
in you app resource dictionary:If you make any custom controls that derive from another control (not
UserControl
, butProgressBar
, for example), you should do this in its static constructor: