
TaskClass.cs:
Код: Выделить всё
namespace Library.TaskClassDirectory;
public sealed class TaskClass : INotifyPropertyChanged
{
public TaskClass(
TimeSpan plannedLaborCost,
TimeSpan actualLaborCost)
{
Labor = new Labor(plannedLaborCost, actualLaborCost, this);
}
private Labor _labor = null!;
public Labor Labor
{
get => _labor;
set
{
if (Equals(value, _labor))
{
return;
}
_labor = value;
OnPropertyChanged();
}
}
private TimeSpan _theDifferenceBetweenThePlannedAndActualEndOfTask;
public TimeSpan TheDifferenceBetweenThePlannedAndActualEndOfTask
{
get => _theDifferenceBetweenThePlannedAndActualEndOfTask;
set
{
if (value.Equals(_theDifferenceBetweenThePlannedAndActualEndOfTask))
{
return;
}
_theDifferenceBetweenThePlannedAndActualEndOfTask = value;
OnPropertyChanged();
}
}
internal void TheDifferenceBetween()
{
TheDifferenceBetweenThePlannedAndActualEndOfTask = Labor.PlannedCost.Subtract(
Labor.ActualCost
);
OnPropertyChanged(nameof(TheDifferenceBetweenThePlannedAndActualEndOfTask));
}
public event PropertyChangedEventHandler? PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private bool SetField(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer.Default.Equals(field, value))
{
return false;
}
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
Код: Выделить всё
namespace Library.TaskClassDirectory;
public class Labor: INotifyPropertyChanged
{
public Labor(TimeSpan plannedCost, TimeSpan actualCost, TaskClass taskClass)
{
PlannedCost = plannedCost;
ActualCost = actualCost;
TaskClass = taskClass;
}
private TimeSpan _plannedCost;
public TimeSpan PlannedCost
{
get => _plannedCost;
set
{
if (value.Equals(_plannedCost))
{
return;
}
if (SetField(ref _plannedCost, value))
{
TaskClass?.TheDifferenceBetween();
}
_plannedCost = value;
OnPropertyChanged();
}
}
private TimeSpan _actualCost;
public TimeSpan ActualCost
{
get => _actualCost;
set
{
if (value.Equals(_actualCost))
{
return;
}
if (SetField(ref _actualCost, value))
{
TaskClass?.TheDifferenceBetween();
}
_actualCost = value;
OnPropertyChanged();
}
}
private TaskClass? _taskClass;
public TaskClass? TaskClass
{
get => _taskClass;
set
{
if (Equals(value, _taskClass))
{
return;
}
_taskClass = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer.Default.Equals(field, value))
return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
Код: Выделить всё
namespace WpfAppForExample.ViewModels;
public class MainViewModel:INotifyPropertyChanged
{
public ObservableCollection TaskClassList { get; set; }
public MainViewModel()
{
TaskClassList = new ObservableCollection();
GetTaskClassList();
}
private void GetTaskClassList()
{
TaskClass taskClass = new TaskClass(TimeSpan.Zero, TimeSpan.Zero);
TaskClassList.Clear();
TaskClassList.Add(taskClass);
}
public event PropertyChangedEventHandler? PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer.Default.Equals(field, value))
{
return false;
}
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
Код: Выделить всё
namespace WpfAppForExample.ViewModels;
public class OutputValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is TimeSpan val && parameter != null && parameter.ToString()!.Contains("IsColor"))
{
if (val > TimeSpan.Zero)
{
return "Red";
}
else if (val < TimeSpan.Zero)
{
return "Green";
}
else
{
return "Black";
}
}
return value;
}
public object ConvertBack(object value, Type targetType, object? parameter, CultureInfo culture) =>
value;
}
Код: Выделить всё
namespace WpfAppForExample
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}
Код: Выделить всё
Код: Выделить всё
Код: Выделить всё
Код: Выделить всё
Невозможно разрешить свойство TheDifferenceBetweenThePlannedAndActualEndOfTask в контексте данных типа WpfAppForExample.ViewModels.MainViewModel. >
Однако всё работает корректно. Почему?
Я пробовал следующие настройки привязки DataTrigger, но все они не работают:
- Binding RelativeSource={RelativeSource Self
- Binding TaskClassList[this].TheDifferenceBetweenThePlannedAndActualEndOfTask
- xmlns:taskClassDirectory="clr-namespace:Library.TaskClassDirectory; Assembly=Library"
Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type TaskClassDirectory:TaskClass}}
Подробнее здесь: https://stackoverflow.com/questions/791 ... atacontext
Мобильная версия