question

JMDeb-5957 avatar image
0 Votes"
JMDeb-5957 asked ·

XAML > Binding SelectedValue to a concatenation of 2 properties

Hi,

I've a Person class

 public class Person
 {
     public string location;
     public string name;
     ...
 }

...and a list of Person

 List<Person> list1 = new List<Person>()
 {
     new Person() { location = "Chicago", name = "Michael" },
     new Person() { location = "", name = "Mario" },
     new Person() { location = "Denver", name = "Michael" }
 };

In a ComboBox, I want to display this list formated that way: name (location). So I've used a Converter and it's working fine until there:

 <ComboBox ItemsSource="{Binding list1}" IsSynchronizedWithCurrentItem="True">
     <ComboBox.ItemTemplate>
         <DataTemplate>
             <TextBlock Text="{Binding Converter={StaticResource concatNameAndLoc}}"/>
         </DataTemplate>
     </ComboBox.ItemTemplate>
 </ComboBox>

 Public Class ConcatNameAndOption
     Implements IValueConverter
     Public Function Convert(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.Convert
         Dim valConv As Person = TryCast(value, Person)
         
         Dim loc As String = valConv.Location
         If loc <> "" Then
             loc = " (" & loc & ")"
         End If
 
         Return valConv.Name & loc
     End Function
     Public Function ConvertBack(ByVal value As Object, ByVal targetType As Type, ByVal parameter As Object, ByVal culture As System.Globalization.CultureInfo) As Object Implements IValueConverter.ConvertBack
         Return value
     End Function
 End Class

I can see the data displayed correctly in my ComboBox: Michael (Chicago) Mario Michael (Denver)

Now, here is my problem: The selected Person will be saved in a XML file (<Person location="Paris">Michel</Person>) and I would like, at loading, that the ComboBox selects this Person (the one with the matching Name and Location concatenation) ...in other words, from the concatenation on the 'saved' person, I want to find the corresponding concatenated person in the list.

How to bind the SelectedValue? I've tryed SelectedValue="{Binding Person, Converter={StaticResource concatNameAndOpt}, NotifyOnSourceUpdated=True}" ...but without succes.

Thanks for reading me! Hope that I was clear!

wpf
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered ·

Hi, find the person in list1 und set selected value. Try following demo:

XAML:

 <Window x:Class="WpfApp1.Window27"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         xmlns:local="clr-namespace:WpfApp27"
         mc:Ignorable="d"
         Title="Window27" Height="450" Width="800">
   <Window.DataContext>
     <local:ViewModel/>
   </Window.DataContext>
   <Window.Resources>
     <local:ConcatNameAndOption x:Key="concatNameAndLoc"/>
   </Window.Resources>
   <StackPanel>
     <ComboBox ItemsSource="{Binding View}" 
               SelectedValue="{Binding SelectedPerson}">
       <ComboBox.ItemTemplate>
         <DataTemplate>
           <TextBlock Text="{Binding Converter={StaticResource concatNameAndLoc}}"/>
         </DataTemplate>
       </ComboBox.ItemTemplate>
     </ComboBox>
   </StackPanel>
 </Window>

And classes:

 using System;
 using System.Collections.Generic;
 using System.ComponentModel;
 using System.Globalization;
 using System.Windows;
 using System.Windows.Data;
 
 namespace WpfApp27
 {
   public class ViewModel
   {
     public ViewModel()
     {
       cvs.Source = list1;
 
       // set selected value
       SelectedPerson = list1.Find((p) =>
       {
         return p.Location == "Paris" && p.Name == "Michael";
       });
     }
 
     public List<Person> list1 = new List<Person>()
      {
          new Person() { Location = "Chicago", Name = "Michael" },
          new Person() { Location = "", Name = "Mario" },
          new Person() { Location = "Paris", Name = "Michael" },
          new Person() { Location = "Denver", Name = "Michael" }
      };
 
     CollectionViewSource cvs = new CollectionViewSource();
     public ICollectionView View { get => cvs.View; }
 
     public Person SelectedPerson { get; set; }
   }
   public class Person
   {
     public string Location { get; set; }
     public string Name { get; set; }
   }
   public class ConcatNameAndOption : IValueConverter
   {
     public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
     {
       Person valConv = value as Person;
       string loc = valConv.Location;
       if (loc != "") loc = " (" + loc + ")";
       return valConv.Name + loc;
     }
     public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value;
   }
 }


· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.