2013-06-25 5 views
2

Я работаю над некоторым приложением, и у меня есть одна проблема. У меня есть два окна (заказы - родители и гости - ребенок). В родительском окне у меня есть один комбинированный блок со списком гостей и одна кнопка для добавления нового гостя. Когда я нажимаю на эту кнопку, открывается окно «Пользователи» (дочернее окно). В дочернем окне я добавляю нового гостя в базу данных, и это отлично работает. Мой вопрос: Как обновить/обновить список со списков в родительском окне после добавления нового гостя в дочернем окне? Я знаю, что изменения в свойстве должны отражаться в представлении без извлечения данных из базы данных (благодаря привязке).Обновить список combobox из другого окна, MVVM

Bookings.xaml

<ComboBox ItemsSource="{Binding Path=Guests}" SelectedItem="{Binding Path=Guest}" Height="25" HorizontalAlignment="Left" IsEditable="True" IsTextSearchEnabled="True" Margin="119,10,0,0" Name="cbGuest" Padding="3,1,1,1" TextSearch.TextPath="Name" VerticalAlignment="Top" VerticalContentAlignment="Center" Width="141" FontFamily="Times New Roman" FontWeight="Bold" FontSize="14"> 
     <ComboBox.ItemTemplate> 
      <DataTemplate> 
       <TextBlock DataContext="{Binding}" Text="{MultiBinding StringFormat='\{0\} ', Bindings={Binding Path=Name}}" /> 
      </DataTemplate> 
     </ComboBox.ItemTemplate> 
    </ComboBox> 
    <Button BorderBrush="Black" Command="{Binding Path=btnAddGuest}" Content="Novi Gost" FontFamily="Times New Roman" FontWeight="Bold" Height="25" HorizontalAlignment="Left" IsDefault="True" Margin="266,10,0,0" Name="btnNewGuest" VerticalAlignment="Top" Width="62" /> 

BookingsViewModel.cs

private tblGuest guest; 
    public tblGuest Guest // Selected guest from combo box 
    { 
     get 
     { 
      return guest; 
     } 
     set 
     { 
      guest = value; 
      OnPropertyChanged("Guest"); 
     } 
    } 

    private ObservableCollection<tblGuest> guests; 
    public ObservableCollection<tblGuest> Guests // Guests list in the combo box 
    { 
     get 
     { 
      return guests; 
     } 
     set 
     { 
      guests = value; 
      OnPropertyChanged("Guests"); 
     } 
    } 

    public ICommand _btnAddGuest; 
    public ICommand btnAddGuest // Command for opening child window 
    { 
     get 
     { 
      if (_btnAddGuest == null) 
      { 
       _btnAddGuest = new DelegateCommand(delegate() 
       { 
        try 
        { 
         Guests guest = new Guests(); 
         guest.ShowDialog(); 
        } 
        catch 
        { 
         Trace.WriteLine("working...", "MyApp"); 
        } 
       }); 
      } 
      return _btnAddGuest; 
     } 
    } 

Guests.xaml

<Button Command="{Binding Path= btnAddGuest}" Content="Dodaj" FontFamily="Times New Roman" FontWeight="Bold" Height="36" HorizontalAlignment="Left" Margin="12,402,0,0" Name="btnAddGuest" VerticalAlignment="Top" Width="62" IsDefault="True" /> 

Эта кнопка (в окне Guest.xaml) добавляет нового гостя в базу данных.

GuestViewModel.cs

private tblGuest guest; 
    public tblGuest Guest // Guest to be added into database 
    { 
     get 
     { 
      return guest; 
     } 
     set 
     { 
      guest = value; 
      OnPropertyChanged("Guest"); 
     } 
    } 

    public ICommand _btnAddGuest; 
    public ICommand btnAddGuest // Command for adding new guest 
    { 
     get 
     { 
      if (_btnAddGuest == null) 
      { 
       _btnAddGuest = new DelegateCommand(delegate() 
       { 
        try 
        { 
         Service1Client wcf = new Service1Client();       
         wcf.AddGuest(Guest); // "AddGuest()" WCF method adds new guest to database 
         wcf.Close(); 
        } 
        catch 
        { 
         Trace.WriteLine("working...", "MyApp"); 
        } 
       }); 
      } 
      return _btnAddGuest; 
     } 
    } 

Как решить эту проблему? Есть ли простой способ? Вы можете, пожалуйста, объясните подробно свое решение, потому что я новичок в WPF, WCF и MVVM ...

С наилучшими пожеланиями, Владимир

+0

Где код для кнопки, которая открывает окно гостей? Если он не беспокоит, он откроет диалоговое окно «Гость-Окно», поэтому в следующей строке после диалога откроется окно «Гость», и вы можете получить коллекцию гостей из базы данных. – Marguth

ответ

1

Просто использовать уже существующую связь с вашей GuestViewModel от вашего BookingsViewModel.

следующее предложение не тестируется, но вы получите идею

public ICommand btnAddGuest // Command for opening child window 
    { 
     get 
     { 
      if (_btnAddGuest == null) 
      { 
       _btnAddGuest = new DelegateCommand(delegate() 
       { 
        try 
        { 
         Guests guest = new Guests(); 
         guest.ShowDialog(); 

         // Add some Logic here and an is save check property to your GuestVM 
         // sample solution 
         // var vm = guest.DataContext as GuestViewModel; 
         // if(vm != null) 
         //  if(vm.IsSaved) 
         //  { 
         //   var model = vm.Guest as tblGuest; 
         //   Guests.Add(model);    // will add him to your list 
         //   Guest = model      // will add him at your selected Guest 
         //  } 
        } 
        catch 
        { 
         Trace.WriteLine("working...", "MyApp"); 
        } 
       }); 
      } 
      return _btnAddGuest; 
     } 
    } 
+0

Ребята, это работает ... Большое спасибо :) – gaja88

0

Если я правильно понял проблему правильно - вы хотите, чтобы получить новый гость из дочернего окна и обновите свою коллекцию в родительском окне - тогда есть много способов сделать это.

Например:

  1. Добавить событие "OnSuccessful" к вашему GuestsViewModel, а затем прикрепить BookingsViewModel.

  2. Реализовать EventAggregator шаблон (абонентский - слушатель)

  3. Просто обновить гость после закрытия дочернего окна (показать как модальный диалог).

0

Если ваше создание дочернего окна от главного окна, а также ваша модели представления ребенка, вы можете либо посмотреть на ваше окно закрыто событии или, если вам нужно знать, прежде чем окно закрывается вы можете также подписаться на свойство изменило событие дочернего окна, когда оно создается, когда свойство изменяется в модели дочернего представления, которое вы можете проверить, чтобы узнать, находится ли его свойство, которое вы хотите. Если так, обновите свой список.

ChildViewModel n = new ChildViewModel() 
n.PropertyChanged += new PropertyChangedEventHandler(n_PropertyChanged); 
void n_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ if(e.PropertyName == "myChangingObject") 
//reload list 
} 
2

Удерживать BookingsViewModel экземпляр в GuestViewModel классе и вызвать BookingsViewModel.OnPropertyChanged("Guest") при добавлении нового гостя (после wcf.AddGuest(Guest); линии).

+0

Спасибо за ответ Андрей, но как удержать экземпляр из BookingsViewModel в GuestViewModel? Я предполагаю, что «BookingsViewModel bvm = new BookingsViewModel();», но где написать это? :) – gaja88

+0

№ Просто создайте конструктор для 'GuestViewModel', который принимает' BookingsViewModel' как параметр: 'GuestViewModel (BookingsViewModel parentViewModel) {...}' –

0

Простой интерфейс обратного вызова может помочь вам.Клиент должен подписаться, и если сервер подталкивает уведомление, то либо заполняет комбобокс, либо обновляется.

Вот учебник: http://idunno.org/archive/2008/05/29/wcf-callbacks-a-beginners-guide.aspx

Я использовал созданный метод «входа» и хранить каждый клиент обратного вызова на стороне сервера. Тогда всякий раз, когда мне нужно было использовать push-уведомление, я просто использовал этот хранимый клиент-обратный вызов. На стороне клиента вы можете обрабатывать полученное сообщение/событие по своему усмотрению.

0

ОК, я добавил эти строки в моей "GuestsViewModel.cs":

private BookingsViewModel _BookingsViewModel; 
    public BookingsViewModel BookViewModel // Property 
    { 
     get 
     { 
      return _BookingsViewModel; 
     } 
     set 
     { 
      _BookingsViewModel = value; 
      OnPropertyChanged("BookViewModel"); 
     } 
    } 

    public GuestsViewModel(BookingsViewModel bvm) // Constructor with one parameter 
    { 
     BookViewModel = bvm; 
    } 

    public ICommand _btnAddGuest; 
    public ICommand btnAddGuest 
    { 
     get 
     { 
      if (_btnAddGuest == null) 
      { 
       _btnAddGuest = new DelegateCommand(delegate() 
       { 
        try 
        { 
         Service1Client wcf = new Service1Client();       

         wcf.AddGuest(Guest); 
         BookingsViewModel.OnPropertyChanged("Guests"); // You said to add this 
         wcf.Close(); 
        } 
        catch 
        { 
         Trace.WriteLine("working...", "MyApp"); 
        } 
       }); 
      } 
      return _btnAddGuest; 
     } 
    } 

вы имели в виду что-то вроде этого выше? Это не работает ... Полагаю, я должен добавить еще одну вещь? К сожалению, может быть, это вопросы глупые, но я не знаю, как решить эту проблему ...

С уважением, Владимир

Смежные вопросы