代码之家  ›  专栏  ›  技术社区  ›  Red_Phoenix

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

  •  1
  • Red_Phoenix  · 技术社区  · 6 年前

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

    正在使用实体框架将组合框绑定到类内的类。鉴于以下情况:

    .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…….

    它没有以正确的格式显示所有者名称。如何以这种方式绑定组合框以获得我想要的输出(如DOE SR、John Michael、Mr.)

    编辑 我也试过这个方法

    .cs伊瓦卢埃克转换器

    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>
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Bizhan    6 年前

    类型 System.Data.Entity.DynamicProxies 被ef用作启用延迟加载的代理。可以通过设置禁用代理创建 ObjectContext.ContextOptions.ProxyCreationEnabled 错误。 link

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

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

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

    link


    你应该记住 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]);
    }