开发者

WPF Converter to look up in generic list

开发者 https://www.devze.com 2023-01-01 18:53 出处:网络
I have a list of data where I keep e.g. countries with code, name and some other data. List<Country> countries = <deserialized objects from file>

I have a list of data where I keep e.g. countries with code, name and some other data.

List<Country> countries = <deserialized objects from file>

which consist of objects like this:

  public class Country
  {
       public string Code { get; set;}
       public string Name { get; set;}
  }

The object which use as a DataContext may look like this:

public class Address
{
    public string StreetName{ get; set;}
    public string CountryCode { get; set;}
}

Then in my XAML I want to do something like this to show the name of the country

<TextBlock Text="{Binding Path=CountryCode, Converter={StaticResource CountryNameLookupConverter}}"/>

But开发者_开发问答 how can I make the CountryNameLookupConverter use the countries list I read from the xml file?


Depending on where you're exposing the countries collection there are a few different options.

If countries exists in Address or some other ViewModel object you change your converter to implement IMultiValueConverter instead of IValueConverter and then use a MultiBinding to pass both CountryCode and countries (exposed as a property). You would then access and cast values[0] and values[1] to use them to do the lookup in the Convert method.

<TextBlock>
    <TextBlock.Text>
        <MultiBinding Converter="{StaticResource CountryNameLookupConverter}">
            <Binding Path="CountryCode" />
            <Binding Path="Countries" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

If you are exposing countries statically (i.e. Lookup.Countries), you can pass the collection to your IValueConverter either as a property or through the ConverterParameter. Here's the converter with a property:

public class CountryNameLookupConverter : IValueConverter
{
    public IEnumerable<Country> LookupList { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Country country = LookupList.FirstOrDefault(c => c.Code.Equals(value));
        if (country == null)
            return "Not Found";
        return country.Name;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Binding.DoNothing;
    }
}

and the converter resource would be declared like:

<local:CountryNameLookupConverter x:Key="CountryNameLookupConverter" LookupList="{x:Static local:Lookup.Countries}"/>

Or to pass into Convert's object parameter instead:

<TextBlock Text="{Binding Path=CountryCode, Converter={StaticResource CountryNameLookupConverter}, ConverterParameter={x:Static local:Lookup.Countries}}" />


One option would be to make your countries object public static and put it in the Country class. eg:

public class Country
{
    public static List<Country> Countries;
    public string Code { get; set;}
    public string Name { get; set;}
}

You could read from your XML file and set this in the constructor for your application or something like that (or wherever it might be necessary). eg:

Country.Countries = <deserialized objects from file>;

that way you can get the list at any time from anywhere in your application.

Edit: You could also use ConverterParameter:

<TextBlock Text="{Binding Path=CountryCode, Converter={StaticResource CountryNameLookupConverter}, ConverterParameter={Binding Path=Countries}}"/>


First of all, you may need an ORM to create your models as they seem to contain a relationship between them. Else check this article to create the EntitySets and EntityRefs manually which helps in lookups. You may also be interested in this.

Whatever it is, ultimately you need to have a list of Address in the Customer Class.

By the way, where does the Address Model come from?

0

精彩评论

暂无评论...
验证码 换一张
取 消