视图中的 DataContext 不会更改,尽管控制器实现了 INotifyPropertyChanged WPF



我有一个视图,我在其中实现了UserControl。此用户控件对我的控制器中的可观察集合进行更改。列表框绑定到此可观察集合。

在我看来,这些更改不会更新。实际上这应该自动发生吗?还是我错了?我在这里错过了什么吗?

<ListView x:Name="ListViewEmployees" ItemsSource="{Binding EmployeeDetails, Mode=TwoWay, NotifyOnTargetUpdated=True}" Grid.Row="0" Grid.Column="7" Grid.RowSpan="5">

我需要在这里添加什么?

使用 .Net 4.5

从设置数据上下文的视图中的代码隐藏:

 var context = new PlanningController();
            DataContext = context;
            context.employeePlanning(date);

规划控制器:

     public class PlanningController : INotifyPropertyChanged
{
    private ObservableCollection<EmployeeDetails> _employeeDetails = null;
    private const string seperator = "; ";
    public void employeePlanning()
    {
        EmployeeDetails = new ObservableCollection<EmployeeDetails>();
        try
        {
            using (var db = new Context())
            {
                var employee = (db.Qualification.Join(db.Employee, qual => qual.QualificationId,
                    emp => emp.QualificationId, (qual, emp) => new EmployeeDetails
                    {
                        EmployeeId = emp.EmployeeId,
                        ShortForm = emp.ShortNameForm,
                        WorkingHours = emp.WorkingHours,
                        Degree = qual.Qualification
                    }));
                foreach (var emp in employee)
                {
                    EmployeeDetails.Add(emp);
                }
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString());
        }
    }
    public ObservableCollection<EmployeeDetails> EmployeeDetails
    {
        get
        {
            return _employeeDetails;
        }
        set
        {
            if (_employeeDetails == value)
            {
                return;
            }
            _employeeDetails = value;
            RaisePropertyChanged();
        }
    }
    private string _text;
    public string Text
    {
        get { return _text; }
        set
        {
            if (value == null)
                return;
            _text = value;
            employeeResourceControlChanged();
        }
    }
    private Brush _brush;
    public Brush Brush
    {
        get { return _brush; }
        set
        {
            _brush = value;
            RaisePropertyChanged();
        }
    }
     public event PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged([CallerMemberName] string propName = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }
    }

    private void employeeResourceControlChanged()
    {
        var enteredText = _text;
        var delimiters = new char[] { ';', ' ' };
        if (enteredText.Length < 3)
            return;
        if (enteredText.Length >= 3)
        {
            var parts = enteredText.Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
            var exists = checkIfEmployeeExists(parts);
            if (exists.Count == 1)
            {
                var text = exists[0] + seperator;
                if (exists[0] == parts[parts.Length - 1])
                {
                    _text = text;
                    _brush = Brushes.White;
                }
                else
                {
                    _text = text + parts[parts.Length - 1];
                    _brush = Brushes.DarkRed;
                }
            }
            else
            {
                if (exists.Count == 0)
                    return;
                var text = String.Join(seperator, exists);
                if (exists[exists.Count - 1] == parts[parts.Length - 1])
                {
                    _text = text + seperator;
                    _brush = Brushes.White;
                }
                else
                {
                    var npart = parts.Distinct().ToList();
                    if (npart.Count() != parts.Count())
                    {
                        _text = text + seperator;
                        _brush = Brushes.White;
                    }
                    else
                    {
                        _text = text + seperator + parts[parts.Length - 1];
                        _brush = Brushes.DarkRed;
                        //TextBoxEmployeeDetails.BorderThickness = new Thickness(2);
                    }
                }
            }
            //TextBoxEmployeeDetails.SelectionStart = TextBoxEmployeeDetails.Text.Length + 1;
        }
    }
    private List<String> checkIfEmployeeExists(string[] empShort)
    {
        var list = new List<string>();
        for (int index = 0; index < EmployeeDetails.Count; index++)
        {
            var employee = _employeeDetails[index];
            for (int i = 0; i < empShort.Length; i++)
            {
                var shortForm = empShort[i];
                if (employee.ShortForm.Contains(shortForm) && shortForm.Length == 3)
                {
                    employee.WorkingHours -= 8;
                    list.Add(employee.ShortForm);
                }
            }
        }
        return list.Distinct().ToList();
    }

"员工详细信息"类

public class EmployeeDetails
{
    public Guid EmployeeId { get; set; }
    public string ShortForm { get; set; }
    public string Degree { get; set; }
    public double WorkingHours { get; set; }
}

用户控件:

public partial class AddEmployeeToShiftControl : UserControl
{
    public AddEmployeeToShiftControl()
    {
        InitializeComponent();

        TextBoxEmployeeDetails.TextChanged += TextBoxEmployeeDetails_TextChanged;
    }
    void TextBoxEmployeeDetails_TextChanged(object sender, TextChangedEventArgs e)
    {
        TextBoxEmployeeDetails.SelectionStart = TextBoxEmployeeDetails.Text.Length + 1;
    }
    public static readonly DependencyProperty BrushProperty = DependencyProperty.Register(
        "Brush", typeof(string), typeof(AddEmployeeToShiftControl), new PropertyMetadata(default(string)));
    public string Brush
    {
        get { return (string)GetValue(BrushProperty); }
        set { SetValue(BrushProperty, value); }
    }
    public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
        "Text", typeof(string), typeof(AddEmployeeToShiftControl), null);
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set
        {
            SetValue(TextProperty, value);
        }
    }
    public static readonly DependencyProperty SelectionStartProperty = DependencyProperty.Register(
        "SelectionStart", typeof(int), typeof(AddEmployeeToShiftControl), new PropertyMetadata(default(int)));
    public int SelectionStart
    {
        get { return (int)GetValue(SelectionStartProperty); }
        set { SetValue(SelectionStartProperty, value); }
    }
    public event PropertyChangedEventHandler PropertyChanged;
    public void SetValueDp(DependencyProperty property, object value,
    [CallerMemberName] String p = null)
    {
        SetValue(property, value);
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(p));
    }

您的员工类,我的意思是 ObservableCollection 中的 T 是否在其公共属性上实现了?你的 RaisePropertyChanged() 很奇怪,你能给我们看一下代码吗?

通常这样的可观察量是这样实现的:

    private ObservableCollection<Employee> _items = new ObservableCollection<Employee>();
    public ObservableCollection<Employee> items
    {
        get { return _items; }
        set
        {
            _items = value;
            PropertyChanged(this, new PropertyChangedEventArgs("items"));
        }
    }
集合

上的这个东西可确保,如果您将项的指针更改为另一个集合,您的视图将保持同步。否则,您将保留对旧集合的引用。

但是为了更改每个员工的属性,您还需要在其属性上实现 INPC 接口。因此,请注意那里的实现。

    public event PropertyChangedEventHandler PropertyChanged = delegate { };

这是包含委托技巧的事情。

PropertyChanged(this, new PropertyChangedEventArgs("items"));

这是触发器,包括那里的属性名称。这是必须的!

在我的情况下,XAML 中的绑定应定义如下:

<ListView ItemsSource="{Binding items}"> 

假设从 XAML 或代码正确设置了数据上下文,这应该可以工作。

最新更新