bound picture to control in WPF without using converter - wpf

i'm having a custom object with Picture as a string (file name only)
and i want to display.
the problem is that the image is stored in "images" directory of the project so the full path is now "images/{image name}"
how can i bind it correctly ?
i can do it easily with converter i guess, but is there any way to avoid it like:
<Image Source="{Binding Path=FullPath+"/"+Picture}"> ?

You could bind to an aggregated property in your ViewModel and then put whatever path you like into that. That way the ViewModel becomes the 'converter'.

Related

WPF - expose binding methods for inherited column

A reoccurring issue I have is needing to create enhanced text columns for datagrids. By that I mean columns that act just like normal text columns, but with an additional graphic or feature, like an image displayed next to the text. So I'm using template columns, but apparently this means having to "start from scratch" in generating a lot of the features expected of a normal text column, such as the textbox editing template:
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox
FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
Text="{Binding Path=[binded text], Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
I want to define a column that's inherited from DataGridTemplateColumn, then dump all this code into it, so I can reuse these columns with any datagrid I wish. But as shown above, I can't declare the binding in the class definition because that obviously depends upon usage.
How can I define an inherited datagrid column that makes use of child controls (specifically the cell editing textbox in this case), but still allows binding to be set for these controls when the column has been declared with xaml inside some actual datagrid?
So far I've tried to expose a method to do this, but it's not working:
Public Class MyTextColumn
Inherits DataGridTemplateColumn
....
Public Property EditorBinding As String
Get....
Set(value As String)
Dim b As New Binding(value)
b.Mode = BindingMode.TwoWay
b.UpdateSourceTrigger = UpdateSourceTrigger.LostFocus
Dim tb = DirectCast(Me.CellEditingTemplate.LoadContent, TextBox)
tb.SetBinding(TextBox.TextProperty, b)
End Set
End Property
Not working, my best guess is I'm not setting the Binding.Source, but I have no idea what I should be setting it to. It's getting pretty frustrating.
So if I understand you correctly, you want to be able to bind the text property of the TextBox to something on the parent control which will hold this child control of yours. You can't do that using the normal property (I'm guessing you got the "Can't bind because it's not the dependency property" exception or something similar).
This is how I usually do it without any problems. First you need to define a dependency property in the code behind. This should show you how to do it in the VB.net (I really really suck at VB.net so I won't pretend to give you any advice on that). Check the first example in VB.net. What you need to change first is from Boolean to String, you will also probably want to change the property name. Be careful to leave the "Property" part of the name where it stands in the example. GetType(MyCode) should be changed to the name of the class where you are implementing the dependency property (the name of your MyTextColumn class)
In the MyTextColumn xaml, it should look something like this:
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<TextBox
FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
Text="{Binding Path=IsSpinning, RelativeSource={RelativeSource AncestorType=DataGridTemplateColumn}, Mode=TwoWay, UpdateSourceTrigger=LostFocus}"/>
I've put the original property name IsSpinning, you should put there your chosen name. Also, you might have to fix the relative source if the base class is not DataGridTemplateColumn. This should pick up anything comming to your custom control.
The final step is to use your control:
<controls:MyTextColumn IsSpinning="{binding PropName}"/>
You basically bind it to whatever string you want. Feel free to write up any problems that you might have with my explanation or code and I'll fix my answer accordingly.

Wpf bind string to the name property

I have a button in a dynamically loaded XAML file.
<Button Name="{Binding Template_Text1}"
Width="800" Height="76"
Content="{Binding Template_Text1}"
Style="{DynamicResource RoundedButton}"/>
If I give a static NAME to the button everything goes ok.
so, how can I bind a string variable to the NAME property?
From the MSDN:
Name is one of the very few dependency properties that cannot be
animated ( IsAnimationProhibited is true in metadata), because the
name itself is vital for targeting an animation. Data binding a Name
is technically possible, but is an extremely uncommon scenario because
a data-bound Name cannot serve the main intended purpose of the
property: to provide an identifier connection point for code-behind.
In other words: what you are doing is very tricky so think again whether or not you really need it.
Keeping #Erno's valuable input in mind above, I think you can change Name of a property via binding through an attached behavior.
<Button local:NameAnimationBehavior.Name="{Binding Template_Text1}" ... />
And inside the NameAnimationBehavior, in NameProperty's dependency property changed handler, change the sender's Name property with e.NewValue.

is there anyway to get Hyperlink content from resource file in WPF

Is there anyway to get hyperlink content from resource file in xaml. I know there is way on back hand code. I have tried using Name="{x:Static Properties:Resources.stringname}" but it throws error
Or if there is any work around?
I have tried Name but it gives an error:Not able to bind to Uid or Name property in XAML
How about:
<Hyperlink NavigateUri="{x:Static Properties:Resources.SomeUrl}">
<Run Text="{x:Static Properties:Resources.SomeUrl_Description}"/>
</Hyperlink>
You cannot bind to the Name in XAML since it is being used internally to create references and it needs to be unique. Some relevant bits from MSDN:
Name is one of the very few dependency properties that cannot be animated (IsAnimationProhibited is true in metadata), because the name itself is vital for targeting an animation. Data binding a Name is technically possible, but is an extremely uncommon scenario because a data-bound Name cannot serve the main intended purpose of the property: to provide an identifier connection point for code-behind.
Names must be unique within a namescope. For more information, see WPF XAML Namescopes.

get context in converter?

I have a usercontrol whose the context is a given object Foo.
I have a textbox in readonly mode, whose the text changes according to a selected value in a combobox (which is bind two-way). The value of the textbox uses the values of a lot of fields in Foo.
For now, I have written a converter Text="{Binding ComboboxValue, Converter={StaticResource MyTextConverter}}, and code-behind, according to the ComboboxValue, I need to return a string composed of other values of Foo. The problem is I can't access the DataContext in the converter, and I can't pass it.
If I bind the context without Path (using Text="{Binding Converter={StaticResource ConnectionStringTextConverter}}), it won't trigger every time my value in the combobox changes (normal).
So, is it possible to it that way ? Or I'm forced to use the Selected event of the combobox ?
Thanks
PS: Actually, what I need is to bind the Text property of the textbox on my DataContext (no Path), but I need the binding to be evaluate each time a property change of the object change. Is this possible ?
You could use the DataContextProxy utility class like this:
Text={Binding ComboBoxValue, Converter={StaticResource MyTextConverter}, ConverterParameter={StaticResource DataContextProxy}}
and then in your converter grab the converter parameter and cast it to a DataContextProxy and use its DataSource property.

WPF Update Binding when Bound directly to DataContext w/ Converter

Normally when you want a databound control to 'update,' you use the "PropertyChanged" event to signal to the interface that the data has changed behind the scenes.
For instance, you could have a textblock that is bound to the datacontext with a property "DisplayText"
<TextBlock Text="{Binding Path=DisplayText}"/>
From here, if the DataContext raises the PropertyChanged event with PropertyName "DisplayText," then this textblock's text should update (assuming you didn't change the Mode of the binding).
However, I have a more complicated binding that uses many properties off of the datacontext to determine the final look and feel of the control. To accomplish this, I bind directly to the datacontext and use a converter. In this case I am working with an image source.
<Image Source="{Binding Converter={StaticResource ImageConverter}}"/>
As you can see, I use a {Binding} with no path to bind directly to the datacontext, and I use an ImageConverter to select the image I'm looking for. But now I have no way (that I know of) to tell that binding to update. I tried raising the propertychanged event with "." as the propertyname, which did not work.
Is this possible? Do I have to wrap up the converting logic into a property that the binding can attach to, or is there a way to tell the binding to refresh (without explicitly refreshing the binding)?
Any help would be greatly appreciated.
Thanks!
-Adam
The workaround here was to add a property to my object (to be used as the datacontext) called "Self" , which simply returned
public Object Self { get { return this; }}
Then in the binding I used this property:
<Image Source="{Binding Path=Self, Converter={StaticResource ImageConverter}}"/>
Then when I call
PropertyChanged(this, new PropertyChangedEventArgs("Self"))
it works like a charm.
Thanks all.
I don't believe there is a way of accomplishing exactly what you need with your current converter. As you mentioned, you could do the calculation in your ViewModel, or you could change your converter into an IMulitValueConverter.
From your specific scenario (the converter tied to a ViewModel class, and a few of its properties), I would lean towards implementing the logic in the ViewModel.
Hmm, you don't show the full implementation. But I think it should update, if the value bound to the GUI provides the PropertyChanged-Event.
Regards

Resources