我成功了:)
我创建了 2 个实现 INotifyPropertyChanged 的类 StaffIncentiveHelperObject 和 StaffIncentiveLineHelperObject。当通过访问者进行更改时,它们会与现有类重叠并触发事件。
正如您可以在 StaffIncentiveHelperObject 的 ObservableCollection 中添加/删除 StaffIncentiveLineHelperObject 的方法一样,这些方法还可以从 EDM 中添加/删除原始对象......这是有效链接对视图所做的更改与数据库的位。
public class StaffIncentiveHelperObject : INotifyPropertyChanged//
{
public delegate void CollectionChangedDelegate();
public static CollectionChangedDelegate CollectionChanged;
public StaffIncentiveHelperObject(staffincentive input)
{
this._StaffIncentive = input;
}
private staffincentive _StaffIncentive;
public staffincentive StaffIncentive
{
get { return _StaffIncentive; }
set
{
if (_StaffIncentive == value) return;
_StaffIncentive = value;
OnPropertyChanged("StaffIncentive");
}
}
public decimal? StaffIncentiveIncrement
{
get
{
return _StaffIncentive.increment;
}
set
{
if (_StaffIncentive.increment != value)
{
_StaffIncentive.increment = value;
OnPropertyChanged("StaffIncentive");
}
}
}
public string StaffIncentiveName
{
get
{
return _StaffIncentive.name;
}
set
{
if (_StaffIncentive.name != value)
{
_StaffIncentive.name = value;
OnPropertyChanged("StaffIncentive");
}
}
}
public byte? StaffIncentiveType
{
get
{
return _StaffIncentive.type;
}
set
{
if(_StaffIncentive.type != value)
{
_StaffIncentive.type = value;
OnPropertyChanged("StaffIncentive");
}
}
}
private ObservableCollection<StaffIncentiveLineHelperObject> _StaffIncentiveLines = new ObservableCollection<StaffIncentiveLineHelperObject>();
public ObservableCollection<StaffIncentiveLineHelperObject> StaffIncentiveLines
{
get { return _StaffIncentiveLines; }
set { _StaffIncentiveLines = value; OnPropertyChanged("StaffIncentiveLines"); }
}
public void AddStaffIncentiveLine( staffincentiveline SIL)
{
SIL.staffincentive = this._StaffIncentive;
_StaffIncentive.staffincentiveline.Add(SIL);
StaffIncentiveLines.Add(new StaffIncentiveLineHelperObject(SIL, this));
//OnPropertyChanged("StaffIncentiveLine");
if (CollectionChanged != null)
{
CollectionChanged.Invoke();
}
}
public void RemoveStaffIncentiveLine(StaffIncentiveLineHelperObject SILHO)
{
_StaffIncentive.staffincentiveline.Remove(SILHO.StaffIncentiveLine);
_StaffIncentiveLines.Remove(SILHO);
//OnPropertyChanged("StaffIncentiveLine");
if (CollectionChanged != null)
{
CollectionChanged.Invoke();
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
var x = PropertyChanged;
if (x != null)
x(this, new PropertyChangedEventArgs(name));
}
#endregion
}
public class StaffIncentiveLineHelperObject : INotifyPropertyChanged//, INotifyCo
{
public StaffIncentiveLineHelperObject(staffincentiveline input, StaffIncentiveHelperObject parent)
{
this._StaffIncentiveLine = input;
this.Parent = parent;
}
public StaffIncentiveHelperObject Parent { get; set;}
private staffincentiveline _StaffIncentiveLine;
public staffincentiveline StaffIncentiveLine
{
get { return _StaffIncentiveLine; }
set
{
if (_StaffIncentiveLine == value) return;
_StaffIncentiveLine = value;
OnPropertyChanged("StaffIncentiveLine");
}
}
public decimal? StaffIncentiveLineLbound
{
get
{
return _StaffIncentiveLine.lbound;
}
set
{
if (_StaffIncentiveLine.lbound != value)
{
_StaffIncentiveLine.lbound = value;
OnPropertyChanged("StaffIncentiveLine");
}
}
}
public double? StaffIncentiveLinePercentage
{
get
{
return _StaffIncentiveLine.percentage;
}
set
{
if (_StaffIncentiveLine.percentage != value)
{
_StaffIncentiveLine.percentage = value;
OnPropertyChanged("StaffIncentiveLine");
}
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string name)
{
var x = PropertyChanged;
if (x != null)
x(this, new PropertyChangedEventArgs(name));
}
#endregion
}
xaml 的 datacontext 设置为 ObservableCollection,它是简单地从 EDM 的现有对象构建的,像这样
ObservableCollection<SupportingObjects.StaffIncentiveHelperObject> myIcentives = new ObservableCollection<SupportingObjects.StaffIncentiveHelperObject>();
foreach (staffincentive SI in db_incentives)
{
StaffIncentiveHelperObject SIHO = new StaffIncentiveHelperObject(SI);
myIcentives.Add(SIHO);
foreach (staffincentiveline SIL in SI.staffincentiveline)
{
SIHO.AddStaffIncentiveLine(SIL);
}
}
然后 XAML 使用访问器显示/更新它。
<TreeView ItemsSource="{Binding}" Name="MainTree">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding StaffIncentiveLines, Converter={StaticResource IncentiveLineHelperObjectSort}, ConverterParameter=StaffIncentiveLineLbound}">
<StackPanel Orientation="Horizontal" >
<TextBox Text="{Binding StaffIncentiveName}" Width="120" />
<Button Tag="{Binding}" Click="addline" Content="Add Line" />
</StackPanel>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate >
<StackPanel Orientation="Horizontal" Margin="150,0,0,0">
<TextBox Text="{Binding StaffIncentiveLineLbound, StringFormat='{}{0:c}'}" Width="120" />
<TextBox Text="{Binding StaffIncentiveLinePercentage}" Width="120" />
<Button Tag="{Binding}" Click="delLine" Content="Remove"/>
</StackPanel>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
排序仅在第一次加载时完成,而不是在添加行时动态完成,这对我来说很好。这是排序转换器(我从网站上的另一个问题中复制了它)
public class IncentiveLineHelperObjectSort : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
System.Collections.ObjectModel.ObservableCollection<StaffIncentiveLineHelperObject> collection = value as System.Collections.ObjectModel.ObservableCollection<StaffIncentiveLineHelperObject>;
ListCollectionView view = new ListCollectionView(collection);
System.ComponentModel.SortDescription sort = new System.ComponentModel.SortDescription(parameter.ToString(), System.ComponentModel.ListSortDirection.Ascending);
view.SortDescriptions.Add(sort);
return view;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return null;
}
}
这是在按下按钮时添加或删除员工激励线的方法。
private void addline(object sender, RoutedEventArgs e)
{
var incentive = ((sender as Button).Tag as StaffIncentiveHelperObject);
incentive.AddStaffIncentiveLine(new staffincentiveline());
TreeViewItem thisTreeViewItem = MainTree.ItemContainerGenerator.ContainerFromItem(incentive) as TreeViewItem;
thisTreeViewItem.IsExpanded = true;
}
private void delLine(object sender, RoutedEventArgs e)
{
var line = ((sender as Button).Tag as StaffIncentiveLineHelperObject);
StaffIncentiveHelperObject thisIncentive = line.Parent;
thisIncentive.RemoveStaffIncentiveLine(line);
TreeViewItem thisTreeViewItem = MainTree.ItemContainerGenerator.ContainerFromItem(thisIncentive) as TreeViewItem;
if (thisIncentive.StaffIncentiveLines.Count == 0)
{
thisTreeViewItem.IsExpanded = false;
}
}
如果其他人有更好的方法或改进方法,我很高兴听到它:)