簡體   English   中英

元素組計數

[英]Element Groups Count

我使用帶有 MVVM 的 WPF 制作了一個 Notes 應用程序。 我想為每個 i 做一個計數器所以有一個任務列表,每個任務都有重要性(無,常規和重要)。 我想制作列表框,顯示每個重要性的任務計數並將其綁定到視圖(每個重要性的計數器),但我不知道如何。 類似的東西——

  1. 總計 - 10
  2. 無 - 5
  3. 常規 - 3
  4. 重要 - 2

任務 Model:

public enum TaskStates
    {
        None,
        Regular,
        Important,
    }

    [DataContractAttribute]
    public class Task : INotifyPropertyChanged
    {
        private string _name;
        private string _desc;

        private TaskStates taskState;
        public SolidColorBrush TaskBG { get; set; }

        [DataMember]
        public DateTime CreationDate { get; private set; }

        [DataMember]
        public TaskStates TaskState
        {
            get { return taskState; }
            set
            {
                TaskBG ??= new SolidColorBrush();
                switch (value)
                {
                    case TaskStates.None:
                        TaskBG.Color = Color.FromRgb(0, 113, 127);
                        break;
                    case TaskStates.Important:
                        TaskBG.Color = Color.FromRgb(180, 60, 60);
                        break;
                    case TaskStates.Regular:
                        TaskBG.Color = Color.FromRgb(53, 165, 75);
                        break;
                }
                taskState = value;
                
                OnPropertyChanged(nameof(TaskState));
            }
        }

        [DataMember]
        public string Name
        {
            get => _name;
            set
            {
                _name = value;
                OnPropertyChanged(nameof(Name));
            }
        }

        [DataMember]
        public string Description
        {
            get => _desc;
            set
            {
                _desc = value;
                OnPropertyChanged(nameof(Description));
            }
        }

        public Task(string name, string desc,DateTime creationDate, TaskStates taskState)
        {
            this._name = name;
            this._desc = desc;
            CreationDate = creationDate;
            TaskState = taskState;
            
        }

        public Task()
        {

        }

        protected void OnPropertyChanged ([CallerMemberName]string prop = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        

        public event PropertyChangedEventHandler PropertyChanged;
    }

視圖模型:

class TaskViewModel : INotifyPropertyChanged
    {        
        public Task CurrentTask { get; set; }


        public DateTime CurrentDate { get; set; }
        IDialogService dialogService;
        IFileService fileService;
        private TaskCommand addTask;
        private TaskCommand removeTask;
        private TaskCommand saveCommand;
        private TaskCommand openCommand;
        private TaskCommand clearCommand;

        public ObservableCollection<Task> Tasks { get; set; }

        #region Command Properties
        public TaskCommand AddCommand
        {
            get
            {
                return addTask ?? (addTask = new TaskCommand(
                    new Action<object>(obj =>
                    {
                        Tasks.Add((obj as Task) ?? new Task("Header", "smth", CurrentDate, TaskStates.None));
                    })
                ));
            }
        }

        public TaskCommand RemoveCommand
        {
            get
            {
                return removeTask ?? (removeTask = new TaskCommand(
                    new Action<object>(obj =>
                    {
                        if (CurrentTask != null)
                            Tasks.Remove(CurrentTask);

                    }), new Func<object, bool>(obj => Tasks.Count > 0)
                    ));
            }
        }

        public TaskCommand SaveCommand
        {
            get
            {
                return saveCommand ?? (saveCommand = new TaskCommand(
                    new Action<object>(obj =>
                    {
                        try
                        {
                            if (dialogService.SaveFileDialog() == true)
                            {
                                fileService.Save(Tasks.ToList(), dialogService.FilePath);
                                dialogService.ShowMessage("File Saved");
                            }
                        }
                        catch (Exception ex)
                        {
                            dialogService.ShowMessage(ex.Message);
                        }

                    }),
                    new Func<object, bool>(obj => Tasks.Count > 0)));

            }
        }
        public TaskCommand OpenCommand
        {
            get
            {
                return openCommand ?? (openCommand = new TaskCommand(
                    new Action<object>(obj =>
                    {
                        try
                        {
                            if (dialogService.OpenFileDialog())
                            {
                                var newTasks = fileService.Open(dialogService.FilePath);
                                if (newTasks.Count > 0)
                                {
                                    Tasks.Clear();
                                    foreach (var item in newTasks)
                                    {
                                        Tasks.Add(item);
                                    }
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            dialogService.ShowMessage(ex.Message);
                        }
                    }
                )));
            }
        }

        public TaskCommand ClearCommand
        {
            get
            {
                return clearCommand ?? (clearCommand = new TaskCommand
                (
                    new Action<object>(obj =>
                    {
                        var res = MessageBox.Show("Are you Sure?", "Caution", MessageBoxButton.YesNo, MessageBoxImage.Warning);
                        if (res == MessageBoxResult.Yes)
                            Tasks.Clear();

                    }),
                    new Func<object, bool>(obj => Tasks.Count > 0)
               ));
            }
        }
        #endregion
        public TaskViewModel()
        {
            CurrentDate = DateTime.Now;
            fileService = new JsonFileService();
            dialogService = new DefaultDialogService();

            Tasks = new ObservableCollection<Task>()
            {
                new Task("Important", "Test",CurrentDate,TaskStates.Important),
                new Task("Regular", "Test",CurrentDate,TaskStates.None),
            };

        }
        protected void OnPropertyChanged([CallerMemberName] string prop = "") => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(prop));
        public event PropertyChangedEventHandler PropertyChanged;
    }

使用ValueConverter來完成此操作。

public class TaskStateCountConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        => $"{parameter} - {((IEnumerable<Task>)value).Count(task => task.TaskState == (TaskStates)parameter)}";

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        => throw new NotImplementedException();
}

XAML (你說你想要一個ListBox ):

<Window.Resources>
    <local:TaskStateCountConverter x:Key="TaskStateCountConverter"/>
</Window.Resources>
<Grid>
    <ListBox>
        <ListBoxItem Content="{Binding Tasks.Count}"/>
        <ListBoxItem Content="{Binding Tasks,
                               Converter={StaticResource TaskStateCountConverter},
                               ConverterParameter={x:Static local:TaskStates.None}}"/>
        <ListBoxItem Content="{Binding Tasks,
                               Converter={StaticResource TaskStateCountConverter},
                               ConverterParameter={x:Static local:TaskStates.Regular}}"/>
        <ListBoxItem Content="{Binding Tasks,
                               Converter={StaticResource TaskStateCountConverter},
                               ConverterParameter={x:Static local:TaskStates.Important}}"/>
    </ListBox>
</Grid>

視圖模型:

public class TaskViewModel : INotifyPropertyChanged
{
    // unchanged parts skipped

    public TaskViewModel()
    {
        Tasks.CollectionChanged += OnTasksChanged;
    }

    private void OnTasksChanged(object sender, EventArgs e)
        => OnPropertyChanged(nameof(Tasks));

這比我最初想象的要復雜一些,因為沒有事件處理程序( Tasks.Count是)不會更新轉換后的值。

當你在做這件事的時候,你也可以為你的着色邏輯創建一個ValueConverter

編輯

要從CurrentTask中更新TaskViewModel

public class TaskViewModel : INotifyPropertyChanged
{
    // unchanged parts skipped

    private Task _currentTask;

    public Task CurrentTask
    {
        get => _currentTask;
        set
        {
            if (value != _currentTask)
            {
                if (_currentTask != null)
                {
                    _currentTask.PropertyChanged -= OnCurrentTaskChanged;
                }
                _currentTask = value;
                _currentTask.PropertyChanged += OnCurrentTaskChanged;
            }
        }
    }

    private void OnCurrentTaskChanged(object sender, PropertyChangedEventArgs e)
    {
        if (e.PropertyName == nameof(Task.TaskState))
        {
            OnPropertyChanged(nameof(Tasks));
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM