今天,要实现TreeView的多选,发现自己犯了好几个错误,其中有些错误已经犯了一次了,现在记下来,特别给自己一些警告。 实现效果如下

注意问题:
实现代码如下:
protected override void OnLoaded()
{
if (Resource.IsNullOrEmpty(SC.CurrentUser.Person))
UI.Alert(SR.NonOperationalStaff, SC.CurrentUser.Name);
else
{
currentUser = SC.CurrentUser;
//根据当前登录的用户,取得相应的职位/角色,因为进入页面时不相应的选择
searchDialog = new Dialog
{
Title = "选择要操作的客服人员",
Width = 400,
Height = 350,
Content = new Grid
{
RowDefinitions = {
new RowDefinition {Height = new GridLength(1, GridUnitType.Star)},
new RowDefinition { Height = new GridLength(0,GridUnitType.Auto)}
},
Margin = new Thickness(5),
Children =
{
(searchTreeView = new TreeView {BorderThickness = new Thickness(0)}).GridRow(0),
new WrapPanel{
HorizontalAlignment = HorizontalAlignment.Center,
Margin = new Thickness (5),
Children = {
new App.Windows.Controls.Button(){Content = "确认", Width = 60, Height=23}.Do( o => o.Click += new RoutedEventHandler(SearchDialogConfirm_Click)),
new App.Windows.Controls.Button(){Content = "取消" , Width = 60,Height=23}.Do(o => o.Click +=new RoutedEventHandler(SearchDialogCancel_Click))
}
}.GridRow(1)
}
}
};
BuildTreeViewFilter();
searchDialog.Show();
}
}
void BuildTreeViewFilter()
{
Account currentAccount = SC.SelectOne(new Query<Account>(q => q.CurAccendant == currentUser && q.Customer == null).Span(s => new object[] { s.CurAccendant, s.CurAccendant.Person }));
Employee employee = SC.SelectOne(new Query<Employee>(q => q.Person == currentUser.Person).Span(s => new object[] { s.Organization, s.Position, s.Person }));
string tvHeaderName = "";
if (employee != null)
{
tvHeaderName = " (" + employee.Organization.Name + ":" + employee.Position.Name + ") ";// +(SC.Select(new Query<Account>(q => q.Parent.Key == currentAccount.Key)).Count).ToString();
}
if (currentAccount != null)
{
searchTreeView.Items.Clear();
TreeViewItem tviAccount = new TreeViewItem();
//tviAccount.FontSize = 15px;
//tviAccount.Background = new SolidColorBrush(Colors.Cyan);
tviAccount.Header = new WrapPanel
{
Children = {
new CheckBox(){Content = currentAccount.CurAccendant.Name + tvHeaderName, Tag = currentAccount}
.Do(o =>
{
o.Checked += TreeViewFilterAccount_Selected;
o.Unchecked += TreeViewFilterAccount_Selected;
})
}
};
tviAccount.Tag = currentAccount;
tviAccount.IsExpanded = true;
CreateChildTreeViewFilter(currentAccount, tviAccount);
searchTreeView.Items.Add(tviAccount);
}
}
void CreateChildTreeViewFilter(Account parentAccount, TreeViewItem currentTreeViewItem)
{
//必须是紫博蓝员工
ResSet<Account> tvNode = SC.Select(new Query<Account>(q => q.Parent.Key == parentAccount.Key && q.Customer == null).Distinct().Span(s => new object[] { s.CurAccendant.Person, s.CurAccendant }));
if (tvNode != null && tvNode.Count > 0)
{
foreach (Account account in tvNode)
{
Employee employee = SC.SelectOne(new Query<Employee>(q => q.Person == account.CurAccendant.Person).Span(s => new object[] { s.Organization, s.Position, s.Person }));
string tvHeaderName = "";
if (employee != null)
{
tvHeaderName = " (" + employee.Organization.Name + ":" + employee.Position.Name + ")";// +(SC.Select(new Query<Account>(q => q.Parent.Key == account.Key)).Count).ToString();
}
TreeViewItem tviAccount = new TreeViewItem();
tviAccount.Header = new WrapPanel
{
Children = {
new CheckBox() { Content = account.CurAccendant.Name + tvHeaderName, Tag = account}
.Do(o =>
{
o.Checked += TreeViewFilterAccount_Selected;
o.Unchecked += TreeViewFilterAccount_Selected;
})
}
};
tviAccount.Tag = account;
tviAccount.IsExpanded = true;
CreateChildTreeViewFilter(account, tviAccount);
currentTreeViewItem.Items.Add(tviAccount);
}
}
}
void TreeViewFilterAccount_Selected(object sender, RoutedEventArgs e)
{
//Account tvAccountFilter = (Account)((TreeViewItem)sender).Tag;
//SetTreeViewFilterAccountSelectedStatus(tvAccountFilter);
var tvi = GetTreeViewItem((sender as CheckBox).Tag as Account);
SetTreeViewFilterAccountSelectedStatus(tvi);
}
TreeViewItem GetTreeViewItem(Account account)
{
foreach (TreeViewItem item in searchTreeView.Items)
{
if ((item.Tag as Account) == account)
{
return item;
}
var tvi = GetTreeViewItem(item, account);
if (tvi != null) return tvi;
}
return null;
}
TreeViewItem GetTreeViewItem(TreeViewItem parent, Account account)
{
foreach (TreeViewItem item in parent.Items)
{
if ((item.Tag as Account) == account)
{
return item;
}
var tvi = GetTreeViewItem(item, account);
if (tvi != null) return tvi;
}
return null;
}
void SetTreeViewFilterAccountSelectedStatus(TreeViewItem tvi)
{
foreach (TreeViewItem item in tvi.Items)
{
var chk = ((WrapPanel)item.Header).Children[0] as CheckBox;
chk.IsChecked = ((tvi.Header as WrapPanel).Children[0] as CheckBox).IsChecked;
//chk.IsChecked = !chk.IsChecked;
//SetTreeViewFilterAccountSelectedStatus(item);
}
}
这棵树还需要实现其它几个方面:checkbox我三种选择状态;checkbox的状态改变时还需要对其子树进行相应的处理。