Display different values in ComboBox based on a conditional from converter - wpf

I have a ComboBox which should display different values based on a condition.
If the SelectedValue's properties Name or Email is not null and is not empty I want to display those.
If above is not true I want to fallback and display the SelectedValue's Username, this is never null or empty.
This is what I have so far.
<ctrls:RadComboBoxExtended Grid.Row="0" Grid.Column="1" ItemsSource="{Binding CurrentValue.LIST_OF_USERS}" SelectedValue="{Binding CurrentValue.User}" focus:FocusExtension.IsFocused="{Binding Focuspoint}">
<ctrls:RadComboBoxExtended.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource MultiNullOrEmptyStrToVisibility}" ConverterParameter="1">
<Binding Path="Name"/>
<Binding Path="Email"/>
</MultiBinding>
</TextBlock.Visibility>
<Run Text="{Binding Name}"/>
<Run Text="("/><Run Text="{Binding Email}"/><Run Text=")"/>
</TextBlock>
</DataTemplate>
</ctrls:RadComboBoxExtended.ItemTemplate>
</ctrls:RadComboBoxExtended>
Above XAML displays all users which have a Name and Email correctly.
How would I go about displaying the "else branch" for this? As of now the users which do not meet the condition of my converter is blank in the ComboBox. How can I display those?

Simplest way is to surround TextBlock with StackPanel or Grid and put also another TextBlock there, setting ConverterParameter="10" and handling it so, that only one of TextBlocks will be visible.
Another possibility is to use ItemTemplateSelector to define which DataTemplate should be used if RadComboBoxExtended has such a property.
<ctrls:RadComboBoxExtended Grid.Row="0" Grid.Column="1" ItemsSource="{Binding CurrentValue.LIST_OF_USERS}" SelectedValue="{Binding CurrentValue.User}" focus:FocusExtension.IsFocused="{Binding Focuspoint}">
<ctrls:RadComboBoxExtended.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock>
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource MultiNullOrEmptyStrToVisibility}" ConverterParameter="1">
<Binding Path="Name"/>
<Binding Path="Email"/>
</MultiBinding>
</TextBlock.Visibility>
<Run Text="{Binding Name}"/>
<Run Text="("/><Run Text="{Binding Email}"/><Run Text=")"/>
</TextBlock>
<TextBlock Text="{Binding Username}">
<TextBlock.Visibility>
<MultiBinding Converter="{StaticResource MultiNullOrEmptyStrToVisibility}" ConverterParameter="10">
<Binding Path="Name"/>
<Binding Path="Email"/>
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
</StackPanel>
</DataTemplate>
</ctrls:RadComboBoxExtended.ItemTemplate>
</ctrls:RadComboBoxExtended>

I would put the choice between name+email vs username in the ViewModel. (One of ViewModel responsibilities is to provide data for View in a convenient format)
public string SelectionText => String.IsNullOrEmpty(Name) && String.IsNullOrEmpty(Email)
? Username
: $"{Name} ({Email})" ;
much shorter DataTemplate and MultiValueConverter is not required
<ctrls:RadComboBoxExtended Grid.Row="0" Grid.Column="1" ItemsSource="{Binding CurrentValue.LIST_OF_USERS}" SelectedValue="{Binding CurrentValue.User}" focus:FocusExtension.IsFocused="{Binding Focuspoint}">
<ctrls:RadComboBoxExtended.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding SelectionText}"/>
</DataTemplate>
</ctrls:RadComboBoxExtended.ItemTemplate>
</ctrls:RadComboBoxExtended>

Related

binding Textblock from two textboxex value in Xaml

I have two textbox txtFName and txtLName . Now I want to display txtFName - txtLName in textblock using binding.
For bind only txtFName I write below code:
<TextBlock x:Name="textblock" Text="{Binding ElementName=txtFName , Path=Text}" Margin="-3,-8,0,0"/>
But I want to display txtFName - txtLName in textblock using binding.
I do not want to write any code in code behind.
Thanks,
You can do that using MultiBinding:
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} - {1}">
<Binding ElementName="txtFName" Path="Text"/>
<Binding ElementName="txtLName" Path="Text"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
The content of a TextBlock is composed of a collection of inline objects, e.g. Runs. Therefore, you can bind txtFName and txtLName to two different runs, e.g. like this:
<TextBlock x:Name="textblock">
<Run Text="{Binding ElementName=txtFName, Path=Text}"/>
<Run Text=" - "/>
<Run Text="{Binding ElementName=txtLName, Path=Text}"/>
</TextBlock>

WPF ComboBox IsEditable at wpf

I have a wpf (and ef) ComboBox that contains two fields first Name and Last name, everything works correctly
,
but I want them to look inside the box (the same idea as IsEditable="True"), but for some reason I can not
There is a solution with TextSearch.TextPath="FirstName",
But every choice appears only the first part which is not what I want, I would also LastName
I add the code
<ComboBox Name="comboBox1" VerticalAlignment="Top"
SelectedValuePath="CustomerId">
<ComboBox.ItemTemplate>
<DataTemplate >
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" >
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="FirstName" />
<Binding Path="LastName" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
And this
BeEntities bmContex = new BeEntities();
public aaa()
{
InitializeComponent();
var t = bmContex.Customers.ToList();
comboBox1.ItemsSource = t;
}
I would appreciate any help

WPF StringFormat databinding text not appearing

I am trying to get the header text of a TreeviewItem to be set in the binding to an XML source. Everything is working fine except the only thing that appears in the header is the text I'm binding to and nothing else in the string format. Example:
<HierarchicalDataTemplate x:Key="LogDataTemp" ItemsSource="{Binding Path=log}">
<TreeViewItem>
<TreeViewItem.Header>
<Binding Path="Attribute[level].Value" StringFormat="TEST \{0\}" />
</TreeViewItem.Header>
</TreeViewItem>
</HierarchicalDataTemplate>
In this case the level value appears but nothing else. I have tried dozens of different ways of approaching this and it seems that nothing works.
Don't escape the braces in the StringFormat. You want to apply the formatting to the 0th-element in your binding.
For instance, with a simple property called "Level":
<TextBlock x:Name="txtUnformatted" Grid.Row="0" Foreground="White" >
<TextBlock.Text>
<Binding Path="Level" />
</TextBlock.Text>
</TextBlock>
<TextBlock x:Name="txtFormatted" Grid.Row="1" Foreground="White">
<TextBlock.Text>
<Binding Path="Level" StringFormat="Test {0:000000}" />
</TextBlock.Text>
</TextBlock>
And the result is something like:
Update
Also, the default implementation of the Header, when you don't add any controls, is a simple ContentPresenter, which doesn't apply formatting. To work around this, simply put a TextBlock into the header, and bind the text you want formatted to that.
<HierarchicalDataTemplate x:Key="LogDataTemp" ItemsSource="{Binding Path=log}">
<TreeViewItem>
<TreeViewItem.Header>
<TextBlock>
<TextBlock.Text>
<Binding Path="Attribute[level].Value"
StringFormat="TEST {0}" />
</TextBlock.Text>
</TextBlock>
</TreeViewItem.Header>
</TreeViewItem>
</HierarchicalDataTemplate>
It is perfectly acceptable (and commonly done) to put controls into a header control (for instance, a grid containing an image and a label). The beauty of WPF.

WPF Object send itself as MultiBinding path

Basically what I need to know is how to send the source of an HierarchicalDataTemplate into a binding, this is what I have:
<HierarchicalDataTemplate DataType="{x:Type myModel:Person}">
<StackPanel Orientation="Horizontal">
<Image Source="Images\User.gif" />
<TextBlock Margin="5,0,0,0" Text="{Binding Name}" />
</StackPanel>
<HierarchicalDataTemplate.ItemsSource>
<MultiBinding Converter="{StaticResource PersonConverter}">
<Binding Path="Name" />
<!-- Here I need something like Binding Path="Self" so I can send the source of the binding (the "Person" object) -->
</MultiBinding>
</HierarchicalDataTemplate.ItemsSource>
</HierarchicalDataTemplate>
So my source is an object of type myModel:Person, I want to be able to send the object itself in the MultiBinding so the PersonConverter can use it.
Thanks for any help.
Wow, I did a crazy wild guess and it worked =S lol, here's the solution
<MultiBinding Converter="{StaticResource PersonConverter}">
<Binding Path="Name" />
<Binding Path="." /> <!-- this sends the source of the binding -->
</MultiBinding>
Thanks!

WPF Commands Buttons ListBoxItems

I Have a listbox defined like below :
<ListBox x:Name="lstMedias" ItemsSource="{Binding Medias}" Width="Auto" Height="Auto">
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding Name}" Tag="{Binding Name}" Click="Button_Click" Command="{Binding Path=LoadSimpleMoviePopupCommand}">
<Button.Resources>
<Converters:LoadMovieMultiConverter x:Key="LoadMovieMultiConverter" />
</Button.Resources>
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource LoadMovieMultiConverter}">
<MultiBinding.Bindings>
<Binding ElementName="DragDropCanvas" />
<Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
</Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
When Trying to call command LoadSimpleMoviePopupCommand, command is not called, but when calling click event, event is raised.
Do You have an idea why ? It is a normal behavior ? Do we have to trick like ListBoxItem doubleclick ?
Probably because the binding failed. Check the output window of VS and see if there are any binding errors. I suspect the LoadSimpleMoviePopupCommand property is not on your data item class (ie. your Media class).
had the same problem, try this
<Button Command="{Binding DataContext.YourCommand,RelativeSource={RelativeSource AncestorType={x:Type ListBox}}}"
it's quite normal, he can't find your command binding inside the listbox because you set something like
<DataTemplate DataType ...
in that listbox so he'll be looking for that binding inside the datatype and not the viewmodel (I assume :)

Resources