组合框在MVVM,WPF和EF中的动态绑定 [英] Dynamic binding of combobox in MVVM, WPF and EF

查看:115
本文介绍了组合框在MVVM,WPF和EF中的动态绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Hello社区,

在我的应用程序中,我有两个组合框。第二个取决于先前选定值的值。但是当我在cb1中选择某些东西时,cb2没有更新。

当我启动我的应用程序时,cb1正确填充了我的数据库中存在的所有客户端(与EnitiyFramework绑定工作)以及当我选择一个时值那里,属性ClientForwarders更新到属于所选客户端的所有转发器,但组合框不显示它们。



我的型号:

Hello Community,
In my Application, I have two comboboxes. The second one depends on the value of the previous Selected Value. But the cb2 is not updated when I select something in cb1.
When I start my Application the cb1 is populated properly with all Clients that exist in my Database (Binding with EnitiyFramework works) and when I select a value there, the property "ClientForwarders" is updated to all forwarders that belong to the client selected, BUT the combobox does not show them.

My Model:

public class Client
    {
        public int ClientId { get; set; }
        public string ClientName { get; set; }

        public virtual ICollection<CommandMapping> CommandMappings { get; set; }
    }

 public class Forwarder
    {
        public int ForwarderId { get; set; }
        public string ForwarderName { get; set; }

        public virtual ICollection<CommandMapping> CommandMappings { get; set; }
    }

 public class CommandMapping
    {
        public int CommandMappingId { get; set; }
        public string CommandMappingName { get; set; }
        
        public virtual Client Client { get; set; }
        public virtual Forwarder Forwarder { get; set; }
    }



查看:


View:

<Window [...]>
	<Window.DataContext>
		<vm:MainWindowViewModel/>
	</Window.DataContext>
	<ComboBox Name="cb1" ItemsSource="{Binding Clients, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="ClientName"  SelectedItem="{Binding SelectedClient}"/>
	<ComboBox Name="cb2" ItemsSource="{Binding ClientForwarders, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="ForwarderName" SelectedItem="{Binding SelectedForwarder}"/>
</Window>



和我的ViewModel:


And my ViewModel:

namespace ProjectXY.ViewModel
{
    public class MainWindowViewModel : INotifyPropertyChanged
    {
        #region ClientHandling
        public IEnumerable<Client> Clients { get; private set; }
        private Client _selectedClient;
        public Client SelectedClient
        {
            get => _selectedClient;
            set
            {
                _selectedClient = value;
                OnPropertyChanged(nameof(SelectedClient));
            }

        }
        #endregion

        #region ForwarderHandling
        public IEnumerable<Forwarder> ClientForwarders { get; private set; }
        private Forwarder _selectedForwarder;
        public Forwarder SelectedForwarder
        {
            get => _selectedForwarder;
            set
            {
                _selectedForwarder = value;
                OnPropertyChanged(nameof(SelectedForwarder));
            }
        }
        #endregion

        private EFDataModel _ctx;

        public MainWindowViewModel()
        {
            LoadData();
        }

        protected void LoadData()
        {
            Refresh();
        }
        public void Refresh()
        {
            _ctx = new DataModel();
            _ctx.Clients.Load();
            _ctx.Forwarders.Load();
            _ctx.CommandMappings.Load();
            Clients = _ctx.Clients.Local.ToList();
        }

        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            switch (propertyName)
            {
                case null:
                    return;
                case nameof(SelectedClient):
                    var forwarderIdList = new List<int>();
                    Task.WaitAll(_ctx.CommandMappings
                        .Where(cm => cm.Client.ClientId == SelectedClient.ClientId)
                        .ForEachAsync(x => forwarderIdList.Add(x.Forwarder.ForwarderId)));
                    ClientForwarders = _ctx.Forwarders.Local.Where(x => forwarderIdList.Contains(x.ForwarderId)).ToList();
                    
                    break;
            }
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

    }
}





我尝试过:



对于调试我直接在Refresh()方法中填写了ClientForwarders属性。这导致(正如预期的那样)所有转发器都显示在cb2中。



What I have tried:

For Debugging I filled the "ClientForwarders" property directly in the "Refresh()" method. That leads to (as expected) all forwarders are being shown in cb2.

推荐答案

您需要为ClientForwarders属性调用属性更改事件更新你的组合框。您可以在属性的setter中或在加载ClientForwarders列表后提升相同内容。
You need to call property changed event for ClientForwarders property to update your combobox. You can raise the same in the setter of your property or after loading ClientForwarders list.


这篇关于组合框在MVVM,WPF和EF中的动态绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆