我正在编写WPF MVVM应用程序。我正在尝试使用转换器在组合框中显示联系人姓名。我不认为我可以使用DisplayMemberPath,因为“全名”列不存在。
使用Entity Framework将ComboBox绑定到类中的一个类。给出以下内容:
.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>
问题在于ComboBox中显示的最终结果是:
System.Data.Entity.DynamicProxies.Contact _.......
它没有以正确的格式显示所有者名称。我如何以这种方式绑定到ComboBox以获得我想要的输出(即,Doe Sr.,John Michael,先生)
EDIT 我也尝试过这种方式
.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>
答案 0 :(得分:0)
EF使用System.Data.Entity.DynamicProxies
类型作为代理来启用延迟加载。您可以通过将ObjectContext.ContextOptions.ProxyCreationEnabled
设置为false来禁用代理创建。 link
但是,建议使用ViewModels作为绑定源而不是EF模型。
您还可以将新属性添加到EF模型(最好是添加到VM)作为每个项目的绑定源:
[NotMapped]
public string FirstLastName { get { return FirstName + ", " + LastName; } }
请记住,DataContext
中的ItemTemplate
引用了集合中的每个元素。因此,类型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]);
}