Set a custom Attached Property with a XAML Setter - wpf

I wanted to set a custom Attached Property that I attached to my Textboxes.
My name space is correctly imported, and used for other things in my UserControl so it works fine.
I can't seem to find the correct syntax for this.
Here is what I currently have (I tried to add brackets at different places, but it doesn't work) :
...
<DataTrigger ...>
<Setter ... />
<Setter Property="(MyCustomXMLNS:TextBoxExtend).MyProperty" Value="..." />
</DataTrigger>
</Style.Triggers>
This is only a syntax problem here, do you guys know how to achieve this ?

You do not use parentheses in a Setter for an attached property, so the correct syntax is
<Setter Property="MyCustomXMLNS:TextBoxExtend.MyProperty" Value="..."/>
You would use parentheses when the property is the source of a Binding, like
<DataTrigger Binding="{Binding Path=(MyCustomXMLNS:TextBoxExtend.MyProperty)}"
Value="...">

Related

WPF XAML string interpolation

I'm struggling to achieve string interpolation in Setter of the TextBlock in XAML.
I have a string with a {0} inside and want this "tag" to be replaced by some text. I'd use Multibinding and break my message into parts, but my app should be translated to other languages. For example, I have message like "Das Verzeichnis {0} wurde nicht gefunden" which due to semantics of different languages may look different, for example "The following path could nont been found: {0}". Sure, in this case I still can paraphrase it and then break into 3 parts to give a proper StringFormat to the Multibinding, but there is no guarantee it will work, let's say in Japanese. I also can't use multiple Runs, since Setter only receives one value.
Is there a way to get something similar to string.Format() in XAML?
UPD: Code:
<DataTrigger Binding="{Binding State}" Value="{x:Static vm:StatesEnum.UnknownError}">
<Setter Property="Visibility" Value="Visible" />
<Setter Property="Text" Value="{Binding to resource string}" />
</DataTrigger>
UPD2: I wrote a simple converter, that makes all that stuff with string formatting. However, Binding seems to be tricky. XAML code below illustrates my problem. I need to bind to the whole DataContext of it, because State from the DataTrigger (first listing) is not sufficient for the text I want, I need some other fields from the bound object.
<Style x:Key="ImageErrorTextStyle" TargetType="{x:Type TextBlock}">
<Setter Property="Text" Value="{Binding Path=???, Converter={StaticResource ImageToError}}" />
</Style>
However, as I found out, use of converter does not allow use of {Binding} (without Path=some_field). Leaving Path empty is allowed, but in this case Convert is only called once (probably creation or initialization of DataContext). The problem is, that the DataContext is declared in code behind and lies in collection, which is not bound to anything, so I have to apply this converter either in code behind or via setters in style. How can I bind Converter to the {Binding} or maybe there is another way of accessing the whole bound object?
Maybe you can try this :)
<DataTrigger Binding="{Binding State}" Value="{x:Static vm:StatesEnum.UnknownError}">
<Setter Property="Visibility" Value="Visible" />
<Setter Property="Text">
<Setter.Value>
<MultiBinding StringFormat="{}{0}{1}">
<Binding Path="" Converter=""/>
<Binding Path="" Converter=""/>
</MultiBinding>
</Setter.Value>
</Setter>
</DataTrigger>

wpf datatrigger + value binding

I have a custom component that should change your alignment as a property of the window changes and getting the value of another property of itself. The property of the window is changing correctly, however, the alignment of the component is not changing. The converter that returns the alignment is also working correctly (it returns Left, Right or Center, depending on the other property of the component). So where is the error? Here is the code of the DataTrigger:
<myComponent.Resources>
<lib:HorizontalAlignmentConverter x:Key="HorizontalAlignmentConverter"/>
<Style TargetType="{x:Type myComponent}" x:Key="HorizontalAligner">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=MainWindow1, Path=myWindowResizedProperty}" Value="True">
<Setter Property="HorizontalAlignment" Value="{Binding Path=myOtherProperty, RelativeSource={RelativeSource Self}, Converter={StaticResource HorizontalAlignmentConverter}}"/>
</DataTrigger>
</Style.Triggers>
</Style>
</myComponent.Resources>
Thanks in advance!
Another question: Is there any way I can reference, in the expression of DataTrigger Binding, the Window object, without using his name? This way would be more generic.
Thanks again!

How to avoid binding error in dropdown due to an extra property in on item in list?

I have a drodown...and a list of three items bound to it - A,B and C.
Both of these derive from same class - ViewModelBase.
B has a property "IsSomethingEnabled". A and C do not have this property.
In the trigger of this dropdown...I have a data trigger...and it is based on the property - "IsSomethingEnabled".
But I get data binding error as this property is not there in A and C.
How do I solve this?
Any help would be appreciated.
EDIT:
I have fixed using below code - Is this right way to do?
<DataTrigger Value="False">
<DataTrigger.Binding>
<PriorityBinding FallbackValue="True">
<Binding Path="IsSomethingenabled" />
</PriorityBinding>
</DataTrigger.Binding>
<Setter Property="IsEnabled"
Value="False" />
</DataTrigger>
You could specify a separate DataTemplate for each type of item by specifying a DataTemplate per type or implementing a a DataTemplate selector.

How to change the control template effectively in WPF?

The subject is that I've defined a customized control bound to a DataContext. And I wished to change the control template dynamically according to the DataContext's specific property values.
There're 2 ways I've thought of,but I have no idea about which way is better.
1.Do not use the control template in a ResourceDictionary and all details of the control are defined in C# code.Use the DependencyProperty CallBack method to render the control when DataContext's property values change.
2.Define control template in the ResourceDictionary and use DataTrigger to change the 'Control.Template' property.
In my application,thousands of instances in this type would be created,so it's really unacceptable if the ControlTemplate changging is not effective.
Could you please give me some advices or better solutions?
Using any standard WPF technique might not be effective if it would involve a thousands of instances of complex controls. See http://msdn.microsoft.com/en-us/magazine/dd483292.aspx.
I would go with MultiBinding + IMultiValueConverter to Control.Template dependency property, since Template would depend on multiple DataContext properties and would, perhaps, involve complex logic.
Perhaps you could used a ContentPresenter in your ControlTemplate to customize parts of your control. You could provide DataTemplates for those customizable parts which are automatically applied.
I would use a style with the data triggers to control which template is displayed. Like this example:
<Style x:Key="Die1Face" TargetType="{x:Type Button}">
<Setter Property="Template" Value="{StaticResource dieNone}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ThrowDie1[0]}" Value="1" >
<Setter Property="Template" Value="{StaticResource dieOneA}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ThrowDie1[0]}" Value="2" >
<Setter Property="Template" Value="{StaticResource dieTwoA}" />
</DataTrigger>
</Style.Triggers>
</Style>
This would give the flexibility you need.

WPF ListView image depending on status column

I'd like to show an icon instead of a value in a listview. Basically, the ListView is bind to ModelView-Class (Observable-Collection as a property in that) and has a column called "status". Depending on status value, I'd like to show a different image. What would be the best way to do it. I read about DataTemplate, but I don't know where to hook in the code to switch the image.
MV-Class constructor looks like:
public TaskViewModel()
{
this.TaskCollection = ac.GetAllTasks();
}
Many thanks in advance,
Adam
I'd use a DataTrigger. Here's an example:
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="Template" Value="{StaticResource DisabledImageTemplate}" />
<Style.Triggers>
<DataTrigger Binding="{Binding Status}" Value="Active">
<Setter Property="Template" Value="{StaticResource ActiveImageTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
If your images path/name dictated by code behind (this is bad but sometimes happens), you could implement IValueConverter and name it like StatusToIconConverter. See here on MSDN with a simple example.
Regarding Data Templates See at the DataTemplateSelector class. Here is also a very simple example.
The key point is to define simple class which just analizes a passed in value and returns an appropriate data template, obviously you have to declare one data template per image.

Resources