1

Как я могу заставить диалоговое окно , которое принимает в свою модель представления список типа IEnumerable<string> и отображает его в ListBox'e, возвратить выбранный элемент переменной типа string либо индекс элемента в IEnumerable? В данном примере я попытался решить проблему передавая ссылку на stringпеременную по цепочке:

внешний код -> код окна -> модель представления

Внешний код:

               //Строковая переменная, которая хранит ссылку на выбранный элемент списка
               string SelectedName = string.Empty;
               //Создаем конструктор окна, передаем в конструктор список и переменную с выбранным элементом
               Window_ListPicker windowCourt = new Window_ListPicker(Statics.CourtNames, ref SelectedName);
               windowCourt.ShowDialog();
               if(SelectedName != string.Empty)
               {
               //Обработка результата
               }
               windowCourt.Close();

Окно Window_ListPicker:

public partial class Window_ListPicker : Window
{
    public Window_ListPicker(IEnumerable<string> sourceList, ref string resultProperty)
    {
        ViewModelListPicker VM = new ViewModelListPicker(ref resultProperty);
        VM.SourceList = sourceList;
        VM.HideAction = new Action(this.Hide);
        DataContext = VM;
        InitializeComponent();
    }
}

Код модели представления ViewModelListPicker:

class ViewModelListPicker : INotifyPropertyChanged
{
    public ViewModelListPicker(ref string selectedItem)
    {
        this.SelectedItem = selectedItem;
    }
    public IEnumerable<string> SourceList { get; set; }
private string selectedItem;
public string SelectedItem
{
    get { return selectedItem; }
    set
    {
        if (value != string.Empty)
        {
            selectedItem = value;
            OnPropertyChanged(&quot;SelectedItem&quot;);
            HideWindow.Execute(null);
        }
    }
}

public Action HideAction { get; set; }


private RelayCommand hideWindow;
public RelayCommand HideWindow
{
    get
    {
        return hideWindow ?? (hideWindow = new RelayCommand(obj =&gt; HideAction()));
    }
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string prop = &quot;&quot;)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }
}

}

Когда я запускаю код, изменение выбранного элемента в модели представления не меняет переменную во внешнем коде. Что я делаю не так? Возможно я выбрал принципиально неправильный подход. Как решить эту задачу?

  • У вас тут есть некое нарушение MVVM подхода, ведь ваше окно явно отвечает и за создание VM слоя (DataContext = VM;) (почитайте это) и работает с данными напрямую (IEnumerable<string> sourceList). MVVM подход означает то, что UI максимально отделяется от логики, весь проект делится на 3 слоя (M - данные (база, сайт, файлы), V - интрфейс (цвет, кнопки, анимации), VM - связующий слой (берет данные из M и готовит данные для V). – EvgeniyZ Jul 18 '21 at 14:22
  • 2
    Касательно самого вопроса, то тут на SO есть несколько отличных ответов, один например этот, где показано как в рамках MVVM подхода реализовать диалоговые окна с возможностью получения ответа. Посмотрите внимательно там на само окно, оно не принимает данные, это простое окно с простым макетом, сама логика в своем VM слое, которым и все управляется. – EvgeniyZ Jul 18 '21 at 14:25

0 Answers0