【问题标题】:Writing common properties to a class file in MVVM将通用属性写入 MVVM 中的类文件
【发布时间】:2013-12-19 21:20:25
【问题描述】:

我有属性CaretIndexInputValue 我的ViewModel 用于Highlighting ComboBox Items which matches the text in PART_EditableTextBox of ComboBox。 所以,我希望它们在一个单独的文件中。因此,我不必在每次声明新视图时都输入它们。但这里的问题是这些CaretIndexInputValue 属性的setter 部分依赖于另一个类的另一个名为IsHighlighted 的属性,并且该类可能会因每个新的数据集合而改变。

我有一个 ViewModel 如下:

public class GroupsViewModel : INotifyPropertyChanged
{
    public GroupsViewModel()
    {
        using (DBEntities db = new DBEntities())
        {
            GroupsAndCorrespondingEffects = (from g in db.Groups
                                             select new GroupAndCorrespondingEffect
                                                        {
                                                            GroupName = g.Name,
                                                            CorrespondingEffect = g.Type_Effect.Name
                                                        }
                                            ).ToList();

            GroupsAndCorrespondingEffects.Add
                                            (
                                                new GroupAndCorrespondingEffect
                                                        {
                                                            GroupName = " Primary",
                                                            CorrespondingEffect = ""
                                                        }
                                            );

            GroupsAndCorrespondingEffects = GroupsAndCorrespondingEffects.OrderBy(g => g.GroupName).ToList();

            Items = (from e in db.Type_Effect
                     select e.Name).ToList();
        }
    }

    public static GroupsViewModel CurrentInstance { get { return Instance; } }

    private List<GroupAndCorrespondingEffect> _groupsAndCorrespondingEffects;
    public List<GroupAndCorrespondingEffect> GroupsAndCorrespondingEffects
    {
        get
        {
            return _groupsAndCorrespondingEffects;
        }
        set
        {
            _groupsAndCorrespondingEffects = value;
            OnPropertyChanged("GroupsAndCorrespondingEffects");
        }
    }

    private int _caretIndex;
    public int CaretIndex
    {
        get { return _caretIndex; }
        set
        {
            _caretIndex = value;
            OnPropertyChanged("CaretIndex");

            for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
            {

                string WordToSearch = InputValue;

                if (_caretIndex != 0 && _caretIndex > 0)
                {
                    WordToSearch = InputValue.Substring(0, _caretIndex);
                }

                if (WordToSearch != null)
                {
                    GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);
                }
            }
        }
    }

    private string _inputValue;
    public string InputValue
    {
        get { return _inputValue; }
        set
        {
            _inputValue = value;
            OnPropertyChanged("GroupsAndCorrespondingEffects");

            for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
            {

                string WordToSearch = _inputValue;

                if (_caretIndex != 0 && _caretIndex > 0 && _caretIndex < _inputValue.Length)
                {
                    WordToSearch = _inputValue.Substring(0, _caretIndex);
                }

                GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(WordToSearch);

            }
        }
    }

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

    public event PropertyChangedEventHandler PropertyChanged;
}

用于获取不同格式数据的Helper Class(Get data in two Columns for a comboBox.)如下:(该类的IsHighLighted属性在CaretIndex和@的setter部分引用987654331@.)

public class GroupAndCorrespondingEffect : INotifyPropertyChanged
{
    private string _groupName;
    public string GroupName
    {
        get
        {
            return _groupName;
        }
        set
        {
            _groupName = value;
            OnPropertyChanged("GroupName");
        }
    }

    private string _correspondingEffect;
    public string CorrespondingEffect
    {
        get
        {
            return _correspondingEffect;
        }
        set
        {
            _correspondingEffect = value;
            OnPropertyChanged("CorrespondingEffect");
        }
    }

    private bool _isHighlighted;
    public bool IsHighlighted
    {
        get
        {
            return _isHighlighted;
        }
        set
        {
            _isHighlighted = value;
            OnPropertyChanged("IsHighlighted");
        }
    }

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

【问题讨论】:

    标签: c# wpf silverlight mvvm combobox


    【解决方案1】:

    如果我正确理解您的问题,您想要做的是将 CaretIndexInputValue 等常见位移动到 抽象基 类。

    请参阅下面的示例代码以了解我的意思:

    基类

    public abstract class ViewModelBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        private int _caretIndex;
    
        public int CaretIndex
        {
            get { return _caretIndex; }
            set
            {
                _caretIndex = value;
                OnPropertyChanged("CaretIndex");
                OnCaretIndexChanged();
            }
        }
    
        private string _inputValue;
        public string InputValue
        {
            get { return _inputValue; }
            set
            {
                _inputValue = value;
                OnPropertyChanged("InputValue");
                OnInputValueChanged();
            }
        }
    
        protected abstract void OnCaretIndexChanged();
    
        protected abstract void OnInputValueChanged();
    }
    

    如果您检查 CaretIndex 和 InputValue 的 Setter,它们将分别执行 OnCaretIndexChangedOnInputValueChanged 抽象方法 - 您将在派生类中实现这些方法。

    现在,您的 GroupViewModel 将从 ViewModelBase 继承并实现这两个抽象方法。

    public class GroupsViewModel : ViewModelBase
    {
        public GroupsViewModel()
        {
            using (DBEntities db = new DBEntities())
            {
                GroupsAndCorrespondingEffects = (from g in db.Groups
                                                 select new GroupAndCorrespondingEffect
                                                 {
                                                     GroupName = g.Name,
                                                     CorrespondingEffect = g.Type_Effect.Name
                                                 }
                                                ).ToList();
    
                GroupsAndCorrespondingEffects.Add
                                                (
                                                    new GroupAndCorrespondingEffect
                                                    {
                                                        GroupName = " Primary",
                                                        CorrespondingEffect = ""
                                                    }
                                                );
    
                GroupsAndCorrespondingEffects = GroupsAndCorrespondingEffects.OrderBy(g => g.GroupName).ToList();
    
                Items = (from e in db.Type_Effect
                         select e.Name).ToList();
            }
        }
    
        public static GroupsViewModel CurrentInstance { get { return Instance; } }
    
        private List<GroupAndCorrespondingEffect> _groupsAndCorrespondingEffects;
        public List<GroupAndCorrespondingEffect> GroupsAndCorrespondingEffects
        {
            get
            {
                return _groupsAndCorrespondingEffects;
            }
            set
            {
                _groupsAndCorrespondingEffects = value;
                OnPropertyChanged("GroupsAndCorrespondingEffects");
            }
        }
    
        protected override void OnCaretIndexChanged()
        {
            for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
            {
                string wordToSearch = InputValue;
    
                if (CaretIndex != 0 && CaretIndex > 0)
                {
                    wordToSearch = InputValue.Substring(0, CaretIndex);
                }
    
                if (wordToSearch != null)
                {
                    GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(wordToSearch);
                }
            }
        }
    
        protected override void OnInputValueChanged()
        {
            OnPropertyChanged("GroupsAndCorrespondingEffects");
    
            for (int i = 0; i < GroupsAndCorrespondingEffects.Count; i++)
            {
    
                string wordToSearch = InputValue;
    
                if (CaretIndex != 0 && CaretIndex > 0 && CaretIndex < InputValue.Length)
                {
                    wordToSearch = InputValue.Substring(0, CaretIndex);
                }
    
                GroupsAndCorrespondingEffects[i].IsHighlighted = GroupsAndCorrespondingEffects[i].GroupName.StartsWith(wordToSearch);
    
            }
        }
    }
    

    如果您想抽象GroupAndCorrespondingEffect 类中删除您的 IsHighlighted 属性,您可以采用类似的方法。

    希望这对您有所帮助或给您一些想法。

    更新

    添加类图

    【讨论】:

    • 您好,先生,很高兴再次在这里见到您。跟着你,我会有问题。我在名为 Groups.xaml 的视图中有一个名为 cbUnder 的 2 列组合框,因此,为了将它的 2 列值组合起来,我创建了名为 GroupAndCorrespondingEffect 的类。现在要获得突出显示的项目,我在此类中声明了 IsHighlighted 属性。现在,如果我为 IsHighlighted 属性创建另一个抽象类,那么它将在这种情况下工作。考虑另一种情况,我的视图中有另一个 ComboBox,它只有 1 列。在第二条评论中继续......
    • .......继续......我不会有另一个课程。我仍然想为那个 ComboBox 设置 IsHighlighted 。现在,如果我有另一个 IsHighlighted 抽象类,那么我的 Viewmodel 也需要从该抽象类继承。但据我所知,一个类不能派生自多个基类。现在你会说我应该在 ViewModelBase 类中创建 IsHighlighted 属性,就像你在回答中建议的那样。但问题是我有另一个没有任何组合框的视图。所以,我再次不需要任何 IsHighlighted 属性。
    • @Khushi 我提到如果你想抽象出 IsHighlighed,你可以做类似的事情。但是,从您的 cmets 看来,这不是您想要的。我不会要求您将 IsHighlighted 移至 ViewModelBase,因为它不属于那里。 IsHighlighted 仅在子 ViewModel 中相关。您是否也有许多 ViewModel 的 IsHighlighed 属性具有重复代码?
    • 是的,我有大约。 60% 的 ViewModel 具有重复的 IsHilighted 属性。
    • 那么,对于所有这些子视图模型,您不能有另一个基类(IsHighlighted 抽象出来)吗?
    猜你喜欢
    • 1970-01-01
    • 2023-04-01
    • 2017-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-08
    相关资源
    最近更新 更多