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