【问题标题】:Binding the results of an IEnumerable<class> to a combobox将 IEnumerable<class> 的结果绑定到组合框
【发布时间】:2013-01-24 08:50:13
【问题描述】:

我正在尝试将 ViewModel 中集合的结果绑定到组合框。下面是我的代码。任何帮助,将不胜感激。如果您需要查看其他内容或需要更多信息,请告诉我。

XAML:

DataContext="clr-namespace:Alliance.Library.Email.EmailViewModel"

  <ComboBox x:Name="cboProviders" ItemsSource="{Binding Source=AddressProviders}" DisplayMemberPath="ProviderName" Grid.Row="0" Grid.Column="1"></ComboBox>

那是我的组合框。我意识到代码是完全错误的,但我是新手,所以我试图通过反复试验来解决它。

代码:

这是在我的 VeiwModel “EmailViewModel.cs”中:

 public IEnumerable<IEmailAddressesProvider> AddressProviders { get; set; }

这是我的界面“IEmailAddressesProvider”:

    public interface IEmailAddressesProvider
    {
        string ProviderName { get; }
        IEnumerable<EmailAddress> GetEmailUsers();
    }
}

包含 GetEmailUsers() 的“EmailAddressProviders.cs”代码:

[Export(typeof(IEmailAddressesProvider))]
    public class EmailAddressProvider : IEmailAddressesProvider
    {
        #region Private Properties

        private static readonly IEncryptionService encryptionService = AllianceApp.Container.GetExportedValue<IEncryptionService>();

        #endregion

        public string ProviderName
        {
            get { return "Alliance Users"; }
        }

        public IEnumerable<EmailAddress> GetEmailUsers()
        {
            IUserRepository userRepo = AllianceApp.Container.GetExportedValue<IUserRepository>();
            IEnumerable<User> users = userRepo.GetAllUsers().Where(a => a.IsDeleted == false).OrderBy(a => a.UserID).AsEnumerable();

            List<EmailAddress> AddressList = new List<EmailAddress>();

            foreach (var user in users)
            {
                if (user.DisplayName != null && user.EmailAddress != null && user.DisplayName != string.Empty && user.EmailAddress != string.Empty)
                    AddressList.Add(new EmailAddress() { DisplayName = encryptionService.DecryptString(user.DisplayName), Email = encryptionService.DecryptString(user.EmailAddress) });
            }

            AddressList.OrderBy(u => u.DisplayName);

            return AddressList;

        }
    }

我使用 MEF 来了解如何设置这些值,我喜欢称之为“魔术”。我没有写这个的电子邮件部分。我只是想照顾组合框中的元素。再次感谢!

【问题讨论】:

  • 1.究竟是什么行不通? 2. 发布您用于绑定的 StaticResource 是如何定义的。
  • 它只是不包含集合,我还没有定义我的静态资源。就像我说的,我对此很陌生。我发现它不是那么直观。
  • 我已经有一段时间没有做 WPF 了,但这不需要是 ObservableCollection,而不是 IEnumerable?
  • @IronMan84 不。observable 的优点很简单,如果 UI 添加/删除/编辑项目,则基础集合也会更改,如果基础集合更新,则 UI 也会更新.如果您使用IEnumerable,则它是该序列到控件的一次性副本。

标签: c# wpf xaml data-binding collections


【解决方案1】:

如果您在任何地方都没有真正的 StaticResource,则不应使用它。对于您的情况,您很可能希望执行以下操作:

GetEmailUsers()方法改为属性(只能绑定属性,不能绑定方法返回值):

public interface IEmailAddressesProvider
{
    string ProviderName { get; }
    IEnumerable<EmailAddress> EmailUsers { get; set;};
}

然后将您的 XAML 更改为:

<ComboBox x:Name="cboProviders" ItemsSource="{Binding AddressProviders.EmailUsers}" Grid.Row="0" Grid.Column="1"></ComboBox>

还要确保将 Page 的 DataContext 设置为 ViewModel 实例。

编辑: 好的,刚刚知道您错误地设置了DataContext。根据您编写的内容,您似乎将其设置在 XAML 中的某个位置,如下所示:

DataContext="clr-namespace:Alliance.Library.Email.EmailViewModel"

这实质上意味着您将数据上下文设置为字符串,然后尝试绑定到该字符串的属性,这些属性当然不存在。我建议您检查运行时输出是否存在绑定错误,以确保是这种情况。

如果确实如此,那么您需要正确设置DataContext。最简单的选择是在视图的构造函数中执行此操作:

public MyView()
{
    DataContext = new Alliance.Library.Email.EmailViewModel();
}

【讨论】:

  • 我将发布 GetEmailUsers() 的代码,看看它是否会改变答案。感谢您的帮助!
  • 我想显示提供商名称而不是电子邮件用户
【解决方案2】:

我认为这就是您想要的(在视图中)。

<ComboBox 
    x:Name="cboProviders" 
    ItemsSource="{Binding Source=AddressProviders}"
    DisplayMemberPath="ProviderName"
    Grid.Row="0" Grid.Column="1"></ComboBox>

DisplayMemberPath 在 MSDN 上。

【讨论】:

  • 我已经实现了这个,但它实际上并没有显示 ComboBox 中的值。它表现得好像有什么东西在那里,但实际上没有任何文字。你知道是什么原因造成的吗?
  • 这在我的情况下有效。我需要绑定到 IEnumerable(表的列)的属性。我试过 ItemsSource="{Binding Source=AddressProviders.ProviderName}" 但没有用,不知道为什么,但你的用了。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 2014-08-13
  • 1970-01-01
相关资源
最近更新 更多