Как связать события выпадающего списка с моделью представления с помощью ICommand - PullRequest
0 голосов
/ 07 ноября 2019

Я относительно новичок в MVVM и хочу привязать свой вид к модели вида. У меня много кода, чтобы перейти от CodeBehind в класс ViewModel.

То, что я хотел бы сделать, это связать события ComboBox с соответствующими методами ViewModel ICommand. Я хочу, чтобы ComboBox отображал «CompanyB» при загрузке представления и когда я делаю выбор, ComboBox должен предоставить мне «CompanyA», «CompanyB» и «CompanyC» в качестве опций для выбора.

ПослеКомпания была выбрана, значения 2 текстовых полей ниже

Nachbest.Empf_Ansprechpartner

Nachbest.Empfaenger_Mail

должны соответственно измениться.

Проблема в моем коде, и ComboBox, и текстовые поля остаются пустыми, и внутри выпадающего списка также нет выбора.

Не могли бы вы помочь мне найти то, что мне здесь не хватает? Заранее благодарим за любую помощь!

XAML (neueNachbestellung.xaml):

<Window xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
    <Grid>
        <StackPanel Grid.Column="0" Margin="25,25,0,0" x:Name="leftStPnl">
            <ComboBox x:Name="cboxEmpfaenger" 
                      ItemsSource="{Binding Empf}" 
                      Text="{Binding Empfaenger}" 
                      FontSize="12" Width="150" Margin="118,0,0,0"                      
                      SelectedItem="{Binding SelValue}">
            </ComboBox>
            <TextBox x:Name="txtEmpfAnsprechpartner" Text="{Binding Empf_Ansprechpartner}" FontSize="12" IsEnabled="False" Width="150" Margin="50,0,0,0"/>    
            <TextBox x:Name="txtEmpfMail" Text="{Binding Empfaenger_Mail}" FontSize="12" IsEnabled="False" Width="150" Margin="73,0,0,0"/>
        </StackPanel>
    </Grid>
</Window>

Код сзади (neueNachbestellung.xaml.cs):

public neueNachbestellung(string someId) 
{
    InitializeComponent();
    this.DataContext = new neueNachbestellungViewModel(someId);
}

Просмотр модели (neueNachbestellungViewModel.cs) :

public class neueNachbestellungViewModel: INotifyPropertyChanged
{
public ICommand LoadCombobox => new DelegateCommand<object>(ExecuteLoadCombobox);
public ICommand ComboboxSelectionChanged => new DelegateCommand<object>(ExecuteComboboxSelectionChanged);
public Nachbestellung Nachbest { get; set; }
private object someObject;
private ObservableCollection<string> _empf;
        public ObservableCollection<string> Empf
        {
            get { return _empf; }
            set
            {
                _empf = value;
                OnPropertyChanged("Empf");
            }
        }
        private string _selValue = "12";
        public string SelValue  
        {
            get { return _selValue; }
            set
            {
                _selValue = value;
                OnPropertyChanged("SelValue");
            }
        }

 public event PropertyChangedEventHandler PropertyChanged;
        public virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

public neueNachbestellungViewModel(string id)
{

    this.Artikel = new ArtikelViewModel();
    this.ArtikelList = new ObservableCollection<Artikel>();
    InitializeReorderModel(id);    
    ExecuteComboboxSelectionChanged(someObject);                        
}

public void InitializeReorderModel(string id)
{
    //set the MODEL
    this.Nachbest = new Nachbestellung();

    //Retrieve and set some values on *VIEW LOAD*!
    var dbOracle = new Datenbank();
    this.Nachbest.Bv = dbOracle.GetBauvorhaben(hv);
    this.Nachbest.Hv = hv;
    this.Nachbest.Bauleiter = dbOracle.GetBauleiter(hv);
    this.Nachbest.Projektleiter = dbOracle.GetProjektleiter(hv);
}

private void ExecuteLoadCombobox(object param)
{
    Empf = new ObservableCollection<string>()
    {
        "CompanyA",
        "CompanyB",
        "CompanyC"         
    };

    //Company B is the standard selection on combobox load                     
    Nachbest.Empf_Ansprechpartner = "CompanyB";
    Nachbest.Empfaenger_Mail = "orders@companyB.com";
}

private void ExecuteComboboxSelectionChanged(object param)
{
    Empf = new ObservableCollection<string>()
    {
        "CompanyA",
        "CompanyB",
        "CompanyC"             
    };

    switch (SelValue)
    {

        case "CompanyA":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyA";
                Nachbest.Empfaenger_Mail = "service@companyA.com";
            }
            break;

        case "CompanyB":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyB";
                Nachbest.Empfaenger_Mail = "orders@companyB.com";
            }
            break;

        case "CompanyC":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyC";
                Nachbest.Empfaenger_Mail = "info@companyC.com";
            }
            break;

        default:
            MessageBox.Show("Something went wrong with the company selection!");
            break;
    }
}
}

Просмотр фрагмента :

enter image description here

1 Ответ

1 голос
/ 07 ноября 2019

Это мое быстрое и грязное решение. Он делает то, что ему нужно, и у меня больше нет этих событий click_button, selection_changed внутри моего кода, но внутри моей модели представления. Это все, что мне нужно на данный момент. Очевидно, не элегантное решение, но оно работает. Я надеюсь, что смогу помочь некоторым разработчикам в будущем, которые столкнутся с подобными проблемами. Просто примечание: свойства ICommand внутри модели представления не являются необходимыми в этом сценарии, но я использую их для обработки событий нажатия кнопки в представлении. Вы можете заменить их собственными свойствами, если вам не нужен класс DelegateCommand в вашем приложении.

XAML (neueNachbestellung.xaml):

<Window>
    <Grid>
        <StackPanel Grid.Column="0" Margin="25,25,0,0" x:Name="leftStPnl">
            <ComboBox x:Name="cboxEmpfaenger" 
                      ItemsSource="{Binding Empf}" 
                      Text="{Binding Empfaenger}" 
                      FontSize="12" Width="150" Margin="118,0,0,0"                      
                      SelectedItem="{Binding SelValue}">
            </ComboBox>
            <TextBox x:Name="txtEmpfAnsprechpartner" DataContext="{Binding Nachbest}" Text="{Binding Empf_Ansprechpartner}" FontSize="12" IsEnabled="False" Width="150" Margin="50,0,0,0"/>    
            <TextBox x:Name="txtEmpfMail" DataContext="{Binding Nachbest}" Text="{Binding Empfaenger_Mail}" FontSize="12" IsEnabled="False" Width="150" Margin="73,0,0,0"/>
        </StackPanel>
    </Grid>
</Window>

Код сзади (neueNachbestellung.xaml.cs):

public neueNachbestellung(string someId) 
{
    InitializeComponent();
    this.DataContext = new neueNachbestellungViewModel(someId);
}

neueNachbestellungViewModel.cs:

public class neueNachbestellungViewModel: INotifyPropertyChanged
{
//public ICommand LoadCombobox => new DelegateCommand<object>(ExecuteLoadCombobox);
public ICommand ComboboxSelectionChanged => new DelegateCommand<object>(ExecuteComboboxSelectionChanged);
public Nachbestellung Nachbest { get; set; }
private object someObject; //DelegateCommand.cs requires an argument
private ObservableCollection<string> _empf;
        public ObservableCollection<string> Empf
        {
            get { return _empf; }
            set
            {
                _empf = value;
                OnPropertyChanged("Empf");
            }
        }
        private string _selValue = "CompanyB"; //default value
        public string SelValue  
        {
            get { return _selValue; }
            set
            {
                _selValue = value;
                OnPropertyChanged("SelValue");
 switch (SelValue)
    {

        case "CompanyA":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyA";
                Nachbest.Empfaenger_Mail = "service@companyA.com";
            }
            break;

        case "CompanyB":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyB";
                Nachbest.Empfaenger_Mail = "orders@companyB.com";
            }
            break;

        case "CompanyC":
            {
                Nachbest.Empf_Ansprechpartner = "CompanyC";
                Nachbest.Empfaenger_Mail = "info@companyC.com";
            }
            break;

        default:
            MessageBox.Show("Something went wrong with the company selection!");
            break;
    }
//setting the Empfaenger property here with the current selected value is necessary for the database insert later on!
Nachbest.Empfaenger = SelValue;
            }
        }

 public event PropertyChangedEventHandler PropertyChanged;
        public virtual void OnPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

public neueNachbestellungViewModel(string id)
{

    this.Artikel = new ArtikelViewModel();
    this.ArtikelList = new ObservableCollection<Artikel>();
    InitializeReorderModel(id);    
    ExecuteComboboxSelectionChanged(someObject);                        
}

public void InitializeReorderModel(string id)
{
    //set the MODEL
    this.Nachbest = new Nachbestellung();

    //Retrieve and set some values on *VIEW LOAD*!
    var dbOracle = new Datenbank();
    this.Nachbest.Bv = dbOracle.GetBauvorhaben(hv);
    this.Nachbest.Hv = hv;
    this.Nachbest.Bauleiter = dbOracle.GetBauleiter(hv);
    this.Nachbest.Projektleiter = dbOracle.GetProjektleiter(hv);
}

private void ExecuteComboboxSelectionChanged(object param)
{
    Empf = new ObservableCollection<string>()
    {
        "CompanyA",
        "CompanyB",
        "CompanyC"             
    };
Nachbest.Empf_Ansprechpartner = "CompanyB";
            Nachbest.Empfaenger_Mail = "orders@companyB.com";
            Nachbest.Empfaenger = SelValue; //if this is left out and there is no selection (just the default remaining unchanged!), Nachbest.Empfaenger will be null!
}
}
...