A way to shorten the record of the code below.
<local:MyUserControl>
<local:MyUserControl.MyDependencyProperty>
<local:MyOtherUserControl>
</local:MyUserControl.MyDependencyProperty>
</local:MyUserControl>
I'd like to write this in one line:
<local:MyUserControl>
<local:MyUserControl.MyDependencyProperty="(..) local:MyOtherUserControl" />
</local:MyUserControl>
Is any posible way to do this? I try using x:Type, DynamicResource, nothing work.
Related
I'm noob as far XAML goes. So please bear with me if I ask stupid questions please. I will try to explain what I want so if you can, please help me. Atm I have code with alot of TextBlocks, let's say 20, and I want to change in all of them text to 0, Text = "0". atm I do all that manualy and I feel stupid. In C# I could just do
private string name = "0";
and in whole program every name will be "0"
can I do that in XAML so I wont have to do manualy every name. Same question is for Margin etc.
Thanks, and sorry if I explained poorly.
There are a couple ways to handle your request. You are probably looking for Styles.
XAML
<Window.Resources>
<Style TargetType='TextBox'>
<Setter Property='Text'
Value='Example' />
<Setter Property='Margin' Value='10,5'/>
</Style>
</Window.Resources>
<StackPanel>
<TextBox />
<TextBox />
<TextBox />
</StackPanel>
Screenshot
[Edit]
The other approach is the one offered by DevEstacion. In the resources section of XAML declare the variable value. Then use the StaticResource markup extension to apply the value to the element property.
Firstly you need to add a reference in the XAML file.
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Create the object like this
<sys:String x:Key="textboxValue">0</sys:String>
And use it in your objects within the xaml file.
<TextBox Text="{StaticResource textboxValue}" />
You can assign the vale on the textbox's Loaded event in the code behind.
I am learning on to the concepts of WPF such as data binding, commands, resources, element bindings, styles etc, which use markup extensions extensively, and i am having problem understanding the meaning behind the Markup classes, as they are being used beyond what i understand they should be used for. So here are a few points i need to clear:
(all code snippets are from Pro WPF in C# 2010 book)
What is the meaning and use of Static extension? It can be used to
declare static resources, which can be declared in as
, but this xaml confuses me:
<Button ... Foreground="{x:Static SystemColors.ActiveCaptionBrush}" >
In {x:Static SystemColors.ActiveCaptionBrush}, what is the role
of static here, and what will change if i use x:Dynamic here? The
book says this xaml is equivalent to this codebehind:
cmdAnswer.Foreground = SystemColors.ActiveCaptionBrush;
This means that if i have a class with static properties, i should
be able to use something like this:
<Button ... Foreground="{x:Static MyClass.SomeStaticProperty}" >
But it didn't work, despite i had created a class, i tried using
local:Static (referring to the local namespace) but VisualStudio
didn't allow me to use it. What is the proper method of achieving
this?
What is the meaning of Binding (beyond obvious meaning, what is
happening when i am binding)? It is used for resource binding, or
data or element binding. I was able to understand element binding,
but binding to objects that are not elements caused problems. For
example:
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},
Path=Source}"></TextBlock>
Here it is binding to the text to the SystemFonts.IconFontFamily
property, what is the use of x:static in this case, and how to bind
it to a property in a class that i have created? Also how to update
the text property of the textfield if the value of the binding
target changes? Due to binding, it should update by itself, is this
the case?
All the examples in the book make use of SystemFonts.IconFontFamily,
none that i have seen explains the use of such binding, and how to
do it for the classes that i create? Some help in this regard is
needed. I want to ask more about binding, but i will do so in a
separate question about binding only.
Finally, recommend a book or resource that explains what is
happening, instead of how to do this and that?
Answers....
1)
You said ...
... This means that if i have a class with static properties, i should be
able to use something like this:
<Button ... Foreground="{x:Static MyClass.SomeStaticProperty}" >
But it didn't work, despite i had created a class, i tried using
local:Static (referring to the local namespace) but VisualStudio
didn't allow me to use it. What is the proper method of achieving
this?
Well your trial attempt was correct but it was incorrect to what term you have applied that namespace token to.... local namespace token applies to the class that is declared under it so...
<Button ... Foreground="{x:Static local:MyClass.SomeStaticProperty}" >
Should work just fine provided that SomeStaticProperty is a valid Brush.
In this example, the whole markup was internally equivalent to Binding as ...
Binding.Source = {x:Type local:MyClass}
Binding.Path = SomeStaticProperty.
2)
You had an example...
<TextBlock Text="{Binding Source={x:Static SystemFonts.IconFontFamily},
Path=Source}">
</TextBlock>
So use the same equivalence from example 1 and apply it to this example...
<TextBlock Text="{Binding Source={x:Type SystemFonts},
Path=IconFontFamily.Source}">
</TextBlock>
3)
I learned this whole thing from MSDN... I dont think we can have any other legitimate source than that.
I would like to put my RowValidationRules class as a resource and then reference the Key on the datagrid but I'm not 100% sure on how to get there.
<Window.Resources><helper:AccountRoleValidationRule x:Key="MyAccountRoleValidator" /></Window.Resources>
<DataGrid.RowValidationRules><helper:AccountRoleValidationRule ValidationStep="UpdatedValue" /></DataGrid.RowValidationRules>
I would like to do something like <DataGrid RowValidationRules="{StaticResource MyAccountRoleValidator}" /> but I get 'RowValidationRules' property is read-only and cannot be set from markup.
In the end I'm going to use FindResource("MyAccountRoleValidator") from my .xaml.vb file to check the validation result on my CanSave() ICommand.
Try element syntax:
<DataGrid.RowValidationRules>
<StaticResource ResourceKey="MyAccountRowValidator"/>
</DataGrid.RowValidationRules>
(StaticResource will not show up in the not so intelligent IntelliSense in VS, but when it is written out the property will)
My control has a property that returns an ICommand object. Using XAML, how to I bind a button to it?
Without knowing anything about the relation of the two I would use element binding. E.g.
<YourControl x:Name="CmdSrc" />
<Button Command={Binding ElementName=CmdSrc, Path=CmdProperty} />
You should think about the approach that a control provides a command. It's seems to me some kind of weird. ;)
Regards
EDIT
Ah ok, it was just a hint. Just in case you didn't think about it.
Here is another way to bind your command. I've to admit that I didn't test it. But I think the following should work too.
When the Button is in the control you could also use relative binding.
<YourControl>
<Button Command={Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type YourControl}}, Path=CmdProperty} />
</YourControl>
Then you don't need a name for the control. I'm avoiding names when ever I can to prevent dirty workarounds in code behind.
Yes, I know it some kind of paranoid. ;)
I'd like an advice to the following problem: I want to embed a Button into a text flow, but when I embed a Button and Label (or TextBlock) into the WrapPanel, I get the first figure:
alt text http://sklad.tomaskafka.com/files/wpf-wrappanel-problem.png
I think that one of solutions could be FlowDocument, but I feel that this is far too heavy for a control simple like this (which could be used in several hundred instances). Do you have some other ideas about how to implement this? Thank you!
EDIT:
One solution could be the following (I didn't know it was possible to put more stuff into TextBlock), but I would lose the ability to bind (which I need):
<TextBlock TextWrapping="Wrap">
<Span>
<Button x:Name="MyButton" Command="{Binding Path=MyCommand}" Content="+" />
<Run x:Name="MyLabel" Text="{Binding Path=Subject}" />
<!--
Problem: binding makes following error:
A 'Binding' cannot be set on the 'Text' property of type 'Run'.
A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
-->
</Span>
</TextBlock>
To bind to Run.Text, checkout the BindableRun class by Fortes. Simple to implement, I use it all over my projects.
I found that implementing BindableRun correctly is pretty tricky - and almost all other available implementations will cause an exception from wpf layouting engine when the bound content changes from null to something non-null - see this problem, keyword "Collection was modified; enumeration operation may not execute."
Corrrect implementation from Microsoft is here - it shows how tricky this really is.
Solution: BindableRun class + the following markup:
<TextBlock>
<Button x:Name="MyButton" Command="{Binding Path=MyCommand}" Content="+" />
<common:BindableRun x:Name="Subject" BindableText="{Binding Path=Subject}"/>
</TextBlock>
Funny thing it works on the designer of a UserControl...
In that case, using the Property Change of your control to set the value to the Run is enough. I mean, if you had something like:
<TextBlock>
<Run Text="{Binding ElementName=thisCtrl, Path=Description}" />
</TextBlock>
Then just name the run, and on your property change handler of your UserControl DependencyProperty get/set the value.