转换器在绑定到EF模型时显示System.Data.Entity.DynamicProxies



我正在编写一个WPF MVVM应用程序。我正在尝试使用转换器在组合框中显示联系人姓名。我认为我不能使用DisplayMemberPath,因为不存在"fullname"列。

正在使用实体框架将组合框绑定到类中的一个类。给定以下内容:

.cs文件

public class Car
{
public int CarId { get; set; }
public string Make { get; set; }
public string Model { get; set; }
public string Year { get; set; }
public Contact Owner { get; set; }
}
public class Contact 
{
public int ContactID { get; set; }
public string Salutation { get; set; }
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Suffix { get; set; }
}
public class MultiBindingConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
string name = "";
if (!(values[0] is Contact Contact))
return name;
switch ((string)parameter)
{
case "LastNameFirst":
name += (!string.IsNullOrEmpty(Contact.LastName)) ? Contact.LastName : "";
name += (!string.IsNullOrEmpty(Contact.Suffix)) ? " " + Contact.Suffix : "";
name += (!string.IsNullOrEmpty(Contact.FirstName)) ? ", " + Contact.FirstName : "";
name += (!string.IsNullOrEmpty(Contact.MiddleName)) ? " " + Contact.MiddleName : "";
name += (!string.IsNullOrEmpty(Contact.Salutation)) ? ", " + Contact.Salutation : "";
break;
case "FormatNormal":
default:
name += (!string.IsNullOrEmpty(Contact.Salutation)) ? Contact.Salutation : "";
name += (!string.IsNullOrEmpty(Contact.FirstName)) ? " " + Contact.FirstName : "";
name += (!string.IsNullOrEmpty(Contact.MiddleName)) ? " " + Contact.MiddleName : "";
name += (!string.IsNullOrEmpty(Contact.LastName)) ? " " + Contact.LastName : "";
name += (!string.IsNullOrEmpty(Contact.Suffix)) ? " " + Contact.Suffix : "";
break;
}
return name;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

.XAML文件

<UserControl.Resources>
<local:MultiBindingConverter x:Key="MBC" />
</UserControl.Resources>
<ComboBox ItemsSource="{Binding Contacts, Mode=OneTime}" // Contacts is a full list of the Contact Class (so its every Owner)
SelectedValuePath="ContactId"
SelectedValue="{Binding Car.Owner.ContactId, Mode=TwoWay}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource MBC}" ConverterParameter="LastNameFirst" >
<Binding Path="Contacts"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

问题是显示在组合框中的最终结果是:

System.Data.Entity.DynamicProxies.Contact_…….

它没有以正确的格式显示所有者名称。我如何以这种方式绑定到ComboBox以获得我想要的输出(即Doe Sr.,John Michael,Mr.(

编辑我也尝试过这种方式

.cs IValueConverter

public class ContactNameConverter : BaseValueConverter<ContactNameConverter>
{
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string name = "";
if (!(value is Contact Contact))
return name;
switch ((string)parameter)
{
case "LastNameFirst":
name += (!string.IsNullOrEmpty(Contact.LastName)) ? Contact.LastName : "";
name += (!string.IsNullOrEmpty(Contact.Suffix)) ? " " + Contact.Suffix : "";
name += (!string.IsNullOrEmpty(Contact.FirstName)) ? ", " + Contact.FirstName : "";
name += (!string.IsNullOrEmpty(Contact.MiddleName)) ? " " + Contact.MiddleName : "";
name += (!string.IsNullOrEmpty(Contact.Salutation)) ? ", " + Contact.Salutation : "";
break;
case "FormatNormal":
default:
name += (!string.IsNullOrEmpty(Contact.Salutation)) ? Contact.Salutation : "";
name += (!string.IsNullOrEmpty(Contact.FirstName)) ? " " + Contact.FirstName : "";
name += (!string.IsNullOrEmpty(Contact.MiddleName)) ? " " + Contact.MiddleName : "";
name += (!string.IsNullOrEmpty(Contact.LastName)) ? " " + Contact.LastName : "";
name += (!string.IsNullOrEmpty(Contact.Suffix)) ? " " + Contact.Suffix : "";
break;
}
return name;
}
public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

.XAML

<ComboBox ItemsSource="{Binding Contacts, Mode=OneTime}"
SelectedValuePath="ContactId"
SelectedValue="{Binding Car.Owner.ContactId, Mode=TwoWay}"
>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=., Converter={local:ContactNameConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>

EF使用类型System.Data.Entity.DynamicProxies作为代理来启用延迟加载。您可以通过将ObjectContext.ContextOptions.ProxyCreationEnabled设置为false来禁用代理创建。链路

但是,建议使用ViewModels而不是EF Models作为绑定的源。

您还可以将一个新属性添加到EF模型(或者最好添加到VM(,作为每个项目的绑定源:

[NotMapped]
public string FirstLastName { get { return FirstName + ", " + LastName; } } 

链路


您应该记住,ItemTemplateDataContext指代集合的每个元素。因此类型为Contact的对象的路径是.而不是Contacts

<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource MBC}" ConverterParameter="LastNameFirst" >
<Binding Path="."/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>

我还注意到您使用了一个具有一个值的多值转换器。你可以这样做:

<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource MBC}" ConverterParameter="LastNameFirst" >
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</ComboBox.ItemTemplate>
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if(parameter == "LastNameFirst")
return string.Format("{0}, {1}", values[0], values[1]);
else
return string.Format("{0}, {1}", values[1], values[0]);
}

最新更新