2015-08-12 2 views
0

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

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

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

На первом коде позади моей точки зрения я зарегистрировал свойство зависимостей с помощью метода если изменение свойства:

//i registered here my property, in the code behind my view "P_Recherche" 

public static readonly DependencyProperty BoolClickDemandeProperty = DependencyProperty.Register("Customer", typeof(bool), 
    typeof(P_Recherche), new PropertyMetadata(false, OnCustomerChangedCallBack)); 

public bool Customer 
{ 
    get { return (bool)GetValue(BoolClickDemandeProperty); } 
    set { SetValue(BoolClickDemandeProperty, value); } 
} 

private static void OnCustomerChangedCallBack(
     DependencyObject sender, DependencyPropertyChangedEventArgs e) 
{ 
    P_Recherche c = sender as P_Recherche; 
    if (c != null) 
    { 
     c.OnCustomerChanged(); 
    } 
} 

//Here is the method/code that i want to start after a "call" (in reality after an update of my boolean) of my other view 

protected virtual void OnCustomerChanged() 
{ 
    bool testDemande = viewModel.ClickDemande(); 
    if (testDemande) 
    { 
     this.posts.DataContext = new vm_Demande(); 

     MinimizeDemandeCall(); 
     MinimizeFamilleCall(); 
     MaximizePostCall(); 
    } 
} 

и на втором взгляде, в коде позади, я объявил свойство моего свойства зависимостей, как это:

public bool Customer 
{ 
    get { return (bool)GetValue(P_Recherche.BoolClickDemandeProperty); } 
    set { SetValue(P_Recherche.BoolClickDemandeProperty, value); } 
} 

И я использовать его, например, в случае нажатия кнопки, где я изменить значение свойства для того, чтобы начать свой метод, который я объявленный когда я зарегистрировал свойство зависимостей:

private void BtNewDemande_OnMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
     Customer = true; 
} 

Когда я нажимаю на этом у меня есть exeption как «свойство зависимости не может быть установлено на объект типа» (извините, что у VS2013 нет на английском), поэтому я думаю, что я что-то пропустил ... но я не могу найти решение моей проблемы после всего этого времени, что я потратил ... большое спасибо за вашу помощь! и я приношу свои извинения за плохой английский :)

+0

вы можете достичь того же, если применить MVVM должным образом в вашем приложении. Любая причина, по которой вы не используете команды для обработки события click в вашей модели просмотра?Вы можете использовать службу сообщений для уведомления других режимов просмотра о событиях. – Zafar

+0

Спасибо за ваш ответ, я был безнадежен со вчерашнего дня, самый простой способ, и после того, как я попробовал, он работает очень хорошо, будет использовать мессенджер (у меня есть MVVM Light), но мой босс хочет удалить посланника из приложения, так что Я пытаюсь найти новое решение. – Nimp

ответ

0

Я рекомендую вам использовать совершенно другой подход и воздерживаться от злоупотреблений механизмами DP-PropertyChanged для распространения нажатия кнопки.

Давайте вернемся назад и подумаем о том, что происходит: пользователь нажимает где-то. Это происходит в определенный момент времени. Насколько я могу судить по вашему сообщению, это не изменяет никаких данных, оно не меняет состояние, которое имеет отношение к вашей логике домена, оно просто меняет, как отображаются большие части вашего пользовательского интерфейса. Как нажимая кнопку , разверните кнопку или откроется раскрывающийся список ComboBox.

Таким образом, это межпредметная связь, поэтому я не буду распространять ее и в viewmodel.

Я бы просто использовал простое старое событие здесь. Позвольте мне показать вам:

public class InnerViewWithButton : UserControl 
{ 
    public InnerViewWithButton() 
    { 
     InitializeComponent(); 
     InnerButton.Click+=(sender,args)=>RaiseInnerButtonClicked(); 
    } 
    public event EventHandler InnerButtonClicked; 
    private void RaiseInnerButtonClicked() 
    { 
     var clickHandlers = InnerButtonClicked; 
     if (clickHandlers != null) clickHandlers(this, EventArgs.Empty); 
    } 
} 

public class InnerViewWithMethod : UserControl 
{ 
    ...ctor... 
    public void DoSomeMagic() 
    { 
     ... 
    } 
} 
public class OuterView : UserControl 
{ 
    public OuterView() 
    { 
     InitializeComponent(); 
     MyInnerViewWithButton.InnerButtonClicked += 
      (sender,args) => MyInnerViewWithMethod.DoSomeMagic(); 
    } 
} 
0

Основная цель иметь ViewModels так, что они могут быть легко проверены. Ваша ситуация требует двух взаимодействующих режимов просмотра. Есть модель мастера и ребенка. Когда Клиент меняет владельца, ребенок должен ответить. Поскольку MVVM Light не может быть и речи, вам нужно будет зарегистрировать модель детского просмотра с моделью основного вида. Пример здесь через INotifyPropertyChanged

public class MasterViewModel : INotifyPropertyChanged 
{ 
    private Customer _customer; 

    public Customer Customer 
    { 
     get { return _customer; } 

     set { _customer = value; RaisePropertyChanged("Customer"); } 
    } 

    private void RaisePropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArg(propertyName); 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
} 

public class ChildViewModel : IDisposable 
{ 
    public ChildViewModel(MasterViewModel masterViewModel) 
    { 
     _masterViewModel = masterViewModel; 
     _masterViewModel.PropertyChanged += OnPropertyChanged; 
    } 

    public void Dispose() 
    { 
     _masterViewModel.PropertyChanged -= OnPropertyChanged; 
     _masterViewModel = null; 
    } 

    private void OnCustomerChanged() 
    { 

     MinimizeDemandeCall(); 
     MinimizeFamilleCall(); 
     MaximizePostCall(); 

    } 

    public void OnPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     if (e.PropertyName == "Customer") OnCustomerChanged(); 
    } 
} 

Теперь вы можете писать тесты:

[TestCase] 
public class GivenCustomerChanged_ThenMaximizePostCall 
{ 
    [Test] 
    public void Test() 
    { 
     var masterViewModel = new MasterViewModel(); 
     using (var childViewModel = new ChildViewModel(masterViewModel)) 
     { 
       masterViewModel.Customer = new Customer(); 
     } 

     // assert that MaximizePostCall was called 
    } 
} 
Смежные вопросы