سؤال

أحتاج إلى معرفة كيفية التواصل بين ViewModels.أنا جديد في MVVM لذا يرجى أن تكون لطيفًا.

هنا مثال مخفف

تعريفات الفئة (افترض أنني قمت بربط الحدث Child.PropertyChanged في ParentViewModel):

public class ParentViewModel : ViewModelBase
{
    public ChildViewModel Child { get; set; }
}

public class ChildViewModel : ViewModelBase
{
    String _FirstName;
    public String FirstName 
    {
        get { return _FirstName; }
        set
        {
            _FirstName = value;
            OnPropertyChanged("FirstName");
        }
    }
}

إليك ما تراه في قاموس الموارد

<DataTemplate DataType="{x:Type vm:ParentViewModel}">
    <vw:ParentView/>
</DataTemplate>

<DataTemplate DataType="{x:Type vm:ChildViewModel}">
    <vw:ChildView/>
</DataTemplate>

والكود خلف ChildView:

public partial class ChildView : UserControl
{
    public QueueView()
    {
        InitializeComponent();
        DataContext = new ChildViewModel();
    }
}

المشكلة الواضحة هي أنه عندما يتم إنشاء مثيل ChildView (من خلال التحديد من DataTemplate)، فإنه يقوم بإنشاء فئة ChildViewModel جديدة ولا يستطيع ParentViewModel الوصول إليها.

فكيف يمكنني إنشاء مثيل DataContext الخاص بالعرض ليكون ViewModel الأصلي الذي تسبب في تحديد DataTemplate؟

الحل الواضح هو دمج الخصائص الموجودة في ChildViewModel في ParentViewModel، لكنني أفضل فصلها لإعادة استخدامها.

أنا متأكد من أن الإجابة تافهة، أود فقط أن أعرف ما هي.:)

شكرا لك مقدما.

هل كانت مفيدة؟

المحلول

ويجب عليك ببساطة إزالة السطر:

DataContext = new ChildViewModel();

وسيتم تعيين DataContext ترى تلقائيا من قبل برنامج الأغذية العالمي. DataTemplates دائما وقد وضعت السياق بياناتهم للبيانات لنموذج (في هذه الحالة ViewModel):

<DataTemplate DataType="{x:Type vm:ChildViewModel}">
    <vw:ChildView/>
</DataTemplate>

والنتيجة النهائية هي أن تتمكن من بناء نموذج جهة نظركم كائنات منفصلة (كل من الأم والطفل الطبقات) ثم عرض في وقت لاحق ببساطة عن طريق توصيل لهم في ضوابط المحتوى.

نصائح أخرى

أسهل طريقة للتواصل بين ViewModels باستخدام أسلوب MVVM هي استخدام نمط الوسيط (EventAggregator في Prism).ويمكن رؤية مثال جيد على هذا النهج في الروابط التالية:

  1. نمط الوسيط MVVM بواسطة ساشا باربر
  2. MVVM + الوسيط بواسطة مارلون غريش

تحقق أيضًا من MVVM عينة إطار المشروع.

ودعونا نقول لديك QueueView يستخدم QueueViewModel.

public class QueueViewModel : INotifyPropertyChanged
{
    public ParentType Parent { get; set; }

    public QueueViewModel(ParentType parent)
    {
        this.Parent = parent;
        foreach (ChildType child in Parent)
        {
            child.PropertyChanged += delegate(object sender,
                PropertyChangedEventArgs e)
            {
                if (e.PropertyName != "IsSelected")
                    return;

                //do something like this:
                Parent.IsSelected = AllChildrenAreSelected();
            };
        }
    }

}

public class ParentType : INotifyPropertyChanged
{
    private bool _isSelected;

    public IList<ChildType> Children { get; set; }
    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            OnPropertyChanged("IsSelected");
        }
    }
}

public class ChildType : INotifyPropertyChanged
{
    private string _name;
    private bool _isSelected;

    public string Name
    {
        get { return _name; }
        set
        {
            _name = value;
            OnPropertyChanged("Name");
        }
    }

    public bool IsSelected
    {
        get { return _isSelected; }
        set
        {
            _isSelected = value;
            OnPropertyChanged("IsSelected");
        }
    }
}

و- QueueView جزء

<StackPanel>
<CheckBlock Text="{Binding Path=Parent.Name}" 
            IsChecked="{Binding Parent.IsSelected}"/>
<ItemsControl ItemsSource="{Binding Path=Parent.Children}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>                                    
            <CheckBox Content="{Binding Path=Name}"
                      IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"/>
        </DataTemplate>
    <ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top