开发者

How can you reference a fully defined control as a resource within WPF?

开发者 https://www.devze.com 2023-01-16 21:01 出处:网络
I am aware I can reference styles & templates from a resource dictionary and I make significant use of them.But what about complete controls?

I am aware I can reference styles & templates from a resource dictionary and I make significant use of them. But what about complete controls?

I can declare a fully defined WPF control, like a button, within the app.xaml as a resource. For example, the app.xaml file defining a button would contain this:

<Button x:Key="HelpButton" Content="?" />

But how can reference it within the xaml markup of a user control so that the button is rendered?

EDIT:

In response to the question of "Why would you want to?" I agree that a button isn't an excell开发者_JAVA百科ent example (it's just an easy one to describe).

What about a polygon (not a control, I know) that you declare in app.xaml and want to use in multiple xaml files?


You can't, and to be honest, I'm not sure why you'd want to. That button is one button, meaning that it can only be in one place (at one time); given that, it makes sense to define a new button in every place you need it. As you've already discovered, that's what template resources are for.

(When I say that you can't, I mean that it's not supported in plain XAML; it's conceivable you could implement IValueConverter in a class that returns the button, and bind it in XAML to the content of a content control. And of course, you could use code to add and remove the button programatically from different containers as necessary. Neither seems like a great option.)


As a side-note to Ben M.'s answer:

Some visuals can be used in this way - things inheriting from ToolTip for instance - but it works only when used in the ToolTip-property:

<UserControl.Resources>
    <local:MyToolTip x:Key="ToolTip"/>
<UserControl.Resources>
<Button ToolTip="{StaticResource ToolTip}"/>

This sorta works, but you really should use styling to do these kinds of things.


The only possibility that makes sense is incorporating some controls in a DataTemplate and using that. The DataTemplate 'dresses up' any object and can include full controls; it's actually quite common to design user controls and compose them using DataTemplates; for example, you could define a DataTemplate like this:

<DataTemplate TargetType="{x:Type viewmodels:MyViewModel}">
  <Button Command={Binding MyCommand} Content={Binding MyCaption} />
</DataTemplate>

Assuming the MyViewModel option contains a string property called MyCaption and an ICommand property called MyCommand, the DataTemplate will be automatically used, if defined within scope, to display visually an instance of the MyViewModel class if:

  • the instance is set as the Content property of a ContentControl or derived control, or
  • the instance is one of many items in a collection displayed using an ItemsControl.

When I say 'in scope', what I actually mean is the DataTemplate is defined in a ResourceDictionary somewhere in the accessible hierarchy of controls; i.e. Application.Resources, Window.Resources etc., down to the level of Grid.Resources if the target control (ContentControl or ItemsControl) is hosted in it.

Of course, you can also specify the DataTemplate without a TargetType, but with an x:Key instead, and use it by manually referencing that Key; for example myListBox.ItemTemplate={StaticResource myKey}.

0

精彩评论

暂无评论...
验证码 换一张
取 消