Setting my custom property Name in XAML - wpf

This is very narrow question and I am hesitant about posting it.
I'm defining some dummy data in the resources of my Grid in order to be able to see how my controls are rendered.
<local:Team x:Key="DummyTeam">
<local:Team.Members>
<local:TeamMember Name="Edeax" Delay="3" />
<local:TeamMember Name="Neled" Delay="3" />
</local:Team.Members>
</local:Team>
One funny bit is I want to define the property ´Name´ of ´TeamMember´ and since it is a commonly used attribute in XAML, Visual Studio complains with the following:
'Microsoft.VisualStudio.DesignTools.Xaml.LanguageService.Semantics.Metadata.ReflectionTypeNode' is implemented in the same assembly, you must set the x:Name attribute rather than the Microsoft.VisualStudio.DesignTools.Xaml.LanguageService.Semantics.Metadata.ReflectionPropertyNode attribute.
It compiles and works fine, but, how to set Name property properly in XAML?

Simply - convert to a nested argument, e.g.:
<local:TeamMember Delay="3" >
<local:TeamMember.Name>Edeax</local:TeamMember.Name>
</local:TeamMember>

Related

How can I make a XAML style override a binding?

This question is for WinRT, but may also be applicable for Silverlight. Say I have databound the Background property of a ListView/ListBox, but I want a that databinding only to be in place when a particular theme is applied. I've implemented themes using Merged Dictionaries of XAML styles. When a different theme is applied, I want it to be statically defined by the style.
Is there a way to achieve this using XAML only?
I've tried placing the "Style" attribute after "Background" in the ListView tag itself, to see if the order of the properties mattered, but that did not seem to have any effect.
Nilzor -
This seems like the kind of place where you would use a Custom Converter. In this way, when the binding happens you can run logical tests and any arbitrary code to return the a value that is acceptable for binding.
WinRT project come with an example of the custom converter which i believe is named BooleanToVisibility Converter.
For the record: This does not NEED to be a conversion (i.e. bound object is bool, convert to Visibility and return it to the Visibility property) it can be a logical test -- The bound object is XYZ derives from ABC & if XYZ.Parent.SomeProperty == someValue return different ABC.
Here is a stack overflow link for Creating / Implementing them:
Binding to a property of a custom converter

Current binding value

I'm writing markup extension. I have XAML like this
<TextBlock Text="{ui:Test SomeInfo}" />
and TestExtension with constructor taking one string argument. I'm getting "SomeInfo" string so everything is find. Now I want to nest extensions and write something like
<TextBlock Text="{ui:Test {Binding PropName}}" />
and it does not work as is. I had to add constructor which takes one argument of System.Windows.Data.Binding type.
Now I need to know
How should I retrieve a current value from the Binding object?
When should I do this? Should I subscribe to changes some way or ask for that value every time in ProvideValue method?
Update1 PropName should be resolved against DataContext of TextBlock.
Update2 Just found related question: How do I resolve the value of a databinding?
Bindings like this will not work because your MarkupExtension has no DataContext and it does not appear in the visual tree and i do not think you are supposed to interact with binding objects directly. Do you really need this extension? Maybe you could make do with the binding alone and a converter?
If not you could create a dedicated class which has bindable properties (by inheriting from DependencyObject), this however would still not give you a DataContext or namescope needed for ElementName or a visual tree needed for RelativeSource, so the only way to make a binding work in that situation is by using a Source (e.g. set it to a StaticResource). This is hardly ideal.
Also note that if you do not directly set a binding the ProvideValue method will only be called once, this means that even if you have a binding in your extension it may not prove very useful (with some exceptions, e.g. when returning complex content, like e.g. an ItemsControl which uses the binding, but you set the extension on TextBlock.Text which is just a string), so i really doubt that you want to use a MarkupExtension like this if the value should change dynamically based on the binding. As noted earlier: Consider converters or MultiBindings for various values instead.

Is there any difference in x:name and name for controls in xaml file?

I am new in Silverlight.
When I add some control to my xaml file with Visual Studio it set controls name with Name property, but there is also x:Name.
Is there any difference and when to use each of them?
Thanks.
In Brief
Yes there is a difference. The bottom line is that x:Name can be used on object elements that do not have Name properties of their own.
A longer explanation
You can only use Name on an element that represents an object that actually does have a Name property. For example anything that derives from FrameworkElement.
The x:Name attribute may be placed on any element that represents an object regardless of whether that object actually has a Name property. If the object does have a Name property then the value of x:Name will be assigned to it hence you can't have both x:Name and Name on the same element.
When an object has a Name property or an x:Name property the value of that property is associated with the objects entry in the object tree. It is via the object tree that the FindName method of a FrameworkElement can find an object. FindName can find objects by name even if that object does not carry a Name property of its own since it uses the name recorded in the object tree.
The autogenerated code for a UserControl will contain field definitions for any element that that has a Name or x:Name property. The InitialiseComponent method that is generated will use the FindName method to assign values to these fields.
Example
The above Xaml creates two fields LayoutRoot of type Grid and MyBrush of type SolidColorBrush. If you were to change x:Name="LayoutRoot" to Name="LayoutRoot" that would change nothing. Grid has a Name property. However try changing x:Name="MyBrush" to Name="MyBrush". That doesn't work because SolidColorBrush doesn't have a name property. With the above Xaml you can then do code like this:-
public MainPage()
{
InitializeComponent();
MyBrush.Color = Colors.LightGray;
}
Open the definition of InitializeComponent and take a look at the auto generated code.
No, you just can't use them both. x:Name is what the XAML preprocessor actually uses and Name is just a convience property provided on the FrameworkElement class to set it.
From the MSDN reference:
If Name is available as a property on an element, Name and x:Name can be used interchangeably, but an error results if both attributes are specified on the same element.
Short answer: if you're writing stuff out in XAML, it's probably best to just use x:Name consistently.
Long answer: A previous answer mentioned that Name is a "convienience" property for accessing x:Name. That's correct. However, now that the tools environment for XAML in both Visual Studio and the Expression series has really matured and you are seeing more and more tool-generated XAML, you are also probably seeing more and more x:Name as opposed to Name. The tools prefer x:Name because that way they don't take a somewhat risky dependency (potentially specific to framework) re: how x:Name and Name are really the same, and they don't need to flipflop between setting Name if something happens to be a FrameworkElement and then x:Name on something like a Storyboard and generating a duality if you were to look at this XAML through something like a DOM. In other words, the "Name" attribute in XAML really is a lot less "convenient" to use nowadays than might have been conceived of in the original API design. Part of the "convenience" was to not have to map x:, but you have to do that anyways for x:Class and by now pretty much everyone has gotten used to using x: attributes and the general principles of XAML markup effectively.
I'm not sure of the statement made by the original poster that VS encourages using Name. Yes, Name appears as an intellisense option, but so does x:Name. And all the cases I see in the templates where an object is given a starting name are using x:Name even tho most of these are FrameworkElements.

How to set properties of a d:DesignInstance in XAML?

I'm using the new d:DesignInstance feature of the 4.0 series WPF tools. Works great!
Only issue I'm having is: how can I set properties on the instance? Given something like this:
<Grid d:DataContext="{d:DesignInstance plugin:SamplePendingChangesViewModel, IsDesignTimeCreatable=True}"/>
How can I set properties on the viewmodel, aside from setting them in its default ctor or routing it through some other object initializer?
I gave this a try but VS gives errors on compile "d:DataContext was not found":
<Grid>
<d:DataContext>
<d:DesignInstance IsDesignTimeCreatable="True">
<plugin:SamplePendingChangesViewModel ActiveTagIndex="2"/>
</d:DesignInstance>
</d:DataContext>
For the moment I'm going back to using a resource and 'd:DataContext={StaticResource SampleData}', where I can set the properties in the resource.
Is there a way to do it via a d:DesignInstance?
As #jberger you should probably use d:DesignData instead of inlining a d:DataContext.
However you can set the d:DataContext inline in the xaml file as well, the secret is to use the correct class (DesignProperties) to qualify the d:DataContext property:
<d:DesignProperties.DataContext>
<plugin:SamplePendingChangesViewModel ActiveTagIndex="2"/>
</d:DesignProperties.DataContext>
How do you know what class to qualify with? Mouse over a property that is set in attribute syntax and a tooltip will appear with the fully qualified property name.
Note also that im not using the d:DesignInstance markup exstension as its job specifically is to create a instance of a type that you provide the name for (or generate a proxy of that type if it cant be instanciated at design-time). Thats not what we want, we want to define the instance in inline xaml in this case.
Indeed, d:DesignData (also a markup extension) works much the same way, except that it looks for a xaml file and deserializes that to the actual instance to use instead of just using the default constructor.
Just for completeness i should also mention that you can use DesignData and DesignInstance with element syntax as well by using their full class names (xxxExtension):
<d:DesignProperties.DataContext>
<d:DesignDataExtension Source="SampleData.xaml"></d:DesignDataExtension>
</d:DesignProperties.DataContext>
This is true for most markup exstensions but its not required to follow this naming convension (The Binding class is a notable exception) More info can be found here:
Markup Extensions and WPF XAML

Given a styled WPF DependencyObject, how can I get the Style Key in code?

I have a set of controls bound to data, on which I would like to programmaticaly add validators to the bindings. Currently I'm able to iterate over the visual tree to find those controls with bindings, and also add my validators to these controls. But to further specify which controls should have specific validation I wanted to use styles. So my XAML looks like this:
<TextBox Name="someTextBox" Style="{StaticResource optionalNumericTextBox}" />
Here, the optionalNumericTextBox style serves both adding a validation error template and as a decorator to indicate that this textbox should have the optional numeric validator applied.
The problem occurs when I'm traversing the visual tree, discovers a control with bindings, and then need to determine the style in use. Currently I've tried
dependencyObject.GetValue(FrameworkElement.StyleProperty)
which gives me a Style object but as far as I can tell, this object does not carry the
'optionalNumericTextBox' value. Is it even possible to determine the key or is this information lost in the XAML reader?
When using StaticResourceExtension, this information is lost at compile time when converting your XAML to BAML. Using DynamicResourceExtension, on the other hand, keeps the key around so the resource can be resolved at runtime. To get at the key, you'll need to use ReadLocalValue():
//this gets the Style
var s = textbox.GetValue(TextBox.StyleProperty);
//this gets a ResourceReferenceExpression
var l = textbox.ReadLocalValue(TextBox.StyleProperty);
The problem is, ResourceReferenceExpression is an internal type, so you'll need to use reflection to pull out the key.
As an alternative to all this, have you considered hijacking the Tag property instead?
<Style x:Key="optionalNumericTextBox" TargetType="TextBox">
<Setter Property="Tag" Value="optionalNumericTextBox"/>
</Style>
Then your code can simply check the Tag property on the TextBox.

Resources