视图中的 DataContext 不会更改,尽管 Controller 实现了 INotifyPropertyChang
本文关键字:尽管 Controller 实现 INotifyPropertyChang DataContext 视图 | 更新日期: 2023-09-27 17:56:04
我有一个视图,我在其中实现了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 或代码正确设置了数据上下文,这应该可以工作。