WPF XamComboBox DisplayMemberPath with concatenated values - wpf

I have the following code -
<igEditors:XamComboEditor ItemsSource="{Binding Instances}"
Margin="5,2,5,2" Width="175" HorizontalAlignment="Left"
SelectedItem="{Binding SelectedInstance,Mode=TwoWay,NotifyOnValidationError=True,ValidatesOnDataErrors=True,ValidatesOnExceptions=True}"
>
<igEditors:XamComboEditor.ComboBoxStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} ({1})">
<Binding Path="Name" />
<Binding Path="Id" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</igEditors:XamComboEditor.ComboBoxStyle>
</igEditors:XamComboEditor>
When I set the SelectedInstance from my viewmodel, the combobox is displaying the type of the object. If I then make a selection, it displays correctly, but I click out of the combobox, losing focus, it reverts back to the object type. If I set the DisplayMemberPath manually to just Name, it works correctly, but I really need it to be a concatenated value for the displaymemberpath.
Can anyone help?
Thanks

The answer to this question was to use the ValueToDisplayTextConverter along with a custom converter. More details can be found here -
http://www.infragistics.com/community/forums/p/77378/390782.aspx

Related

Wpf Multibinding in a template or style

I have a class with many properties (not in a list) which must be switchable in view. The converter itself works fine using multibinding.
<TextBox Grid.Row="1" Grid.Column="5">
<TextBox.Text>
<MultiBinding Converter="{StaticResource IntValueConvertor}">
<Binding Path="property1" />
<Binding Path="IntegerDisplay" />
</MultiBinding>
</TextBox.Text>
</TextBox>
In the code, "IntegerDisplay" is a property which is defined in my VM.
Property1 is one of the many properties which must be viewed differently (depending on IntegerDisplay).
What I want to avoid is the need of adding the whole multibinding convertor to each textbox.
Something in this style:
<TextBox
Grid.Row="1"
Grid.Column="4"
Text="{Binding Path=Property1, Converter={StaticResource IntValueConvertor}}" />
I know this code does not work!
I tried using a style, but I could not get to the value of property1.
Is it the best way to use a style or is a datatemplate better?
Kind regards
I recommend sticking with a style and here's a basic start to doing so.
<!--This will go in your resources-->
<Style x:Name="TextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Text" Value="{Binding Path=Property1, Converter={StaticResource IntValueConverter}, ConverterParameter=IntegerDisplay}"/>
</Style>
<!--This will go in your Display-->
<TextBox Style="{StaticResource TextBoxStyle}"/>

How to set foreground on part of multi binding when concatenating two properties in WPF XAML?

I am displaying two property values using multi-binding in WPF XAML.
I would want to set first/second value by different color.
<DataGridTemplateColumn Header="ConcatCol"
Width="60">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock TextAlignment="Right">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Setter Property="Text">
<Setter.Value>
<MultiBinding StringFormat="{} {0:C1} / {1:C1}">
<Binding Path="FirstProp" />
<Binding Path="SecondProp" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</TextBlock.Style>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
So basically you can see that I am displaying two property values in a single cell but separating them by "/". I am also specifying the string format for each of the property.
Now my question is How can I display the value before "/" in Green color and the latter in Red color?
You could actually use Textblock with multiple runs:
<TextBlock TextAlignment="Right">
<Run Text="{Binding FirstProp}" Foreground="Green"/> / <Run Text="{Binding SecondProp}" Foreground="Red"/>
</TextBlock>

How can I binding a listboxitem content in a muiltbinding?

I am doing my first project using wpf. I really need your help and suggestion. Thanks in advance.
I am building a screen, which has two listboxes A & B. Listbox A is binding to items load from database. listbox B is binding to a statics list. When user selects an item in listbox A, the associate item will be highlighted in listbox B. I am doing it by using MultiBinding in a listboxtitem. I'd like to pass selected data object and listboxitem content. The Convert() will take these two variables and check them. If match, it will return true to IsSelected property of item and highlight it. But it seems item content (statics string) can't be passed to converter(). What should I do?
see my xaml code:
<ListBox Name="AbsenseCode" ItemsSource="{Binding absenseCodeItems}" Grid.Row="1" Grid.Column="1" Grid.RowSpan="5" Margin="20,0,20,5" >
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="IsSelected">
<Setter.Value>
<MultiBinding Converter="{StaticResource IsItemSelected}">
<Binding ElementName="FilterListbox" Path="SelectedItem"/>
<Binding Path="Content"/>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
when debugging, the second binging variable, content of item, is "{DependencyProperty.UnsetValue}".
this is a few months old, but I had a similar situation.
First, build a iMultiValueConveter that will compare two values and return the result to a string. "true" or "false" or "yes" or "no".
then in the XAML, define a style that can be triggered by the converter return. In this, ListBoxB has an ellipse where the fill will be green if the values match, red if they dont:
<Window.Resources>
<myNamespace:IsEqualConverter x:Key="IsEqualConverter" />
</Window.Resources>
<ListBox Name="ListBoxA" ItemsSource="{Binding}">
</ListBox>
<ListBox Name="ListBoxB" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<StackPanel>
<StackPanel.Resources>
<!-- style triggered by converter result -->
<Style TargetType="Ellipse" x:Key="EllipseStyle">
<Setter Property="Fill" Value="#E5E5E5" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=result,Path=Text}" Value="true">
<Setter Property="Fill" Value="Green" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=result,Path=Text}" Value="false">
<Setter Property="Fill" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<Ellipse Height="50" Width="50" Style="{StaticResoure EllipseStyle}" />
<TextBlock x:Name="value0" Text="{Binding ElementName=ListBoxA,Path=SelectedItem.(Whatever),Mode=OneWay}" />
<TextBlock x:Name="value1" Text="{Data Binding you want to compare to}" VerticalAlignment="Center" HorizontalAlignment="Left" />
<TextBlock x:Name="result">
<TextBlock.Text>
<MultiBinding Converter="{StaticResource IsEqualConverter}">
<Binding ElementName="value0" Path="Text" />
<Binding ElementName="value1" Path="Text" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</ListBox.ItemTemplate>
</ListBox>

Bind a property to an existing Binding

I have an interface with multiple buttons. I'd like to enable or disable these buttons according to a 'complex' condition. I declared this MultiBinding as an application resource in order to avoid code repetition:
<MultiBinding x:Key="MyMultiBinding" Converter="{StaticResource ResourceKey=MyConverter}">
<Binding Path="IsConnected" />
<Binding Path="IsOpened" />
</MultiBinding>
Here is how I declare my button:
<Button Name="MyButton" Content="Click me!" IsEnabled="{StaticResource ResourceKey=MyMultiBinding}" />
At runtime, I get the following error: "Set property IsEnabled threw an exception... MultiBinding is not a valid value for property IsEnabled".
I can't figure why this is not working. Could you please point me to the right way to do this? Thank you.
You can't set the boolean IsEnabled property to a value of type MultiBinding. That is what is happening.
As #Viv pointed out, you could declare a Style to do the heavy lifting:
<Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{StaticResource ResourceKey=MyConverter}">
<Binding Path="IsConnected" />
<Binding Path="IsOpened" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
<Button Name="MyButton" Content="Click me!" Style="{StaticResource ButtonStyle}" />
This works well if the Button DataContext has those properties. It works especially well if they each have a different DataContext they are bound to, enabling them for different reasons.
If they are all bound to the same DataContext, or the properties are on a different object, you could use the Freezable Trick to provide a value that your buttons would bind to:
<BindingProxy x:Key="isEnabled">
<BindingProxy.Data>
<MultiBinding Converter="{StaticResource ResourceKey=MyConverter}">
<Binding Path="IsConnected" />
<Binding Path="IsOpened" />
</MultiBinding>
</BindingProxy.Data>
</BindingProxy>
<Button Name="MyButton" Content="Click me!" IsEnabled="{Binding Data, Source={StaticResource isEnabled}}" />
I don't know if this is the best solution, but wrapping the MultiBinding into a style, as Viv said, did the trick. Here is the code of the Style :
<Style x:Key="MyStyle" TargetType="Button">
<Style.Setters>
<Setter Property="IsEnabled">
<Setter.Value>
<MultiBinding Converter="{StaticResource ResourceKey=MyConverter}">
<Binding Path="IsConnected" />
<Binding Path="IsDataAccessOpened" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
And the code of the button :
<Button Name="MyButton" Content="Click me!" Style={StaticResource ResourceKey=MyStyle} />

Including objects binding in MultiBinding command parameter

I am attempting to use a <MultiBinding> to pass two parameters to my ViewModel's command but am having issues getting the XAML parser to accept my attempts.
Consider the following ListView contained within my UserControl which is bound to a collection of Ticket objects.
<ListView x:Name="lvTicketSummaries"
ItemsSource="{Binding TicketSummaries}"
ItemContainerStyle="{DynamicResource ResourceKey=ListViewItem}"
IsSynchronizedWithCurrentItem="True">
The respective style ListViewItem
<Style x:Key="ListViewItem" TargetType="{x:Type ListViewItem}">
<Setter Property="ContextMenu" Value="{DynamicResource ResourceKey=cmListViewItem}"/>
<!-- A load of irrelevant stuff ->
</Style>
And the referenced ContextMenu item where the source of my query sits;
<!-- ContextMenu DataContext bound to UserControls view model so it can access 'Agents' ObservableCollection -->
<ContextMenu x:Key="cmListViewItem" DataContext="{Binding RelativeSource={RelativeSource AncestorType={x:Type UserControl}}, Path=DataContext}">
<MenuItem Header="Send as Notification" ItemsSource="{Binding Path=Agents}">
<MenuItem.ItemContainerStyle>
<Style TargetType="{x:Type MenuItem}">
<!-- Display the name of the agent (this works) -->
<Setter Property="Header" Value="{Binding Path=Name}"/>
<!-- Set the command to that of one on usercontrols viewmodel (this works) -->
<Setter Property="Command" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}}, Path=DataContext.SendTicketNotification}" />
<Setter Property="CommandParameter">
<Setter.Value>
<MultiBinding Converter="{StaticResource ResourceKey=TicketNotificationParameterConverter}">
<MultiBinding.Bindings>
<!-- This SHOULD be the Agent object I clicked on to trigger the Command. This does NOT work, results in either exception or 'UnsetValue' -->
<Binding Source="{Binding}" />
<!-- Also pass in the Ticket item that was clicked on to open the context menu, this works fine -->
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListView}}" Path="SelectedItem" />
</MultiBinding.Bindings>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
</MenuItem.ItemContainerStyle>
</MenuItem>
</ContextMenu>
So here is what I am attempting to do;
The context menu has a single item "Send ticket as notification" which, when selected, lists all the available Agents which can receive said notification. This works.
When I click on one of these agent options, I want the context menu item to send both the ticket item that was clicked on from the listview to show the context menu (this works) AND the Agent item I selected from the context menu. I have half-achieved this with the MultiBinding
<MultiBinding Converter="{StaticResource ResourceKey=TicketNotificationParameterConverter}">
<MultiBinding.Bindings>
<!-- This works, it sends the Ticket object to the Converter -->
<Binding RelativeSource="{RelativeSource AncestorType={x:Type ListView}}" Path="SelectedItem" />
<!-- This caused an exception saying that I can only set 'Path' property on DependencyProperty types -->
<Binding Path="{Binding}" />
</MultiBinding.Bindings>
</MultiBinding>
Now although the actual set-up of the context menu seems some what complicated to me. The actual specification that one of the MultiBinding parameters should be the actual item bound to the clicked ContextMenu.MenuItem seems quite a simple command. The context menu correctly lists all Agents and so I would of thought that simply asking for this current object to be sent through as a command parameter, simple. I have also tried;
<Binding RelativeSource={RelativeSource AncestorType={x:Type MenuItem}} Path="SelectedItem" />
as well as
<Binding RelativeSource={RelativeSource AncestorType={x:Type ContextMenu}} Path="SelectedItem" />
But all that gets sent to the Parameter converter is UnsetValue
Thank you for your time and any suggestions you might have.
This line is odd:
<Binding Path="{Binding}" />
Is the current DataContext a string that would suffice as a path that would find something in the current DataContext which is in fact not a string after all? Makes perfect sense.
Did you mean to do this instead which binds to the DataContext?
<Binding />

Resources