gpt4 book ai didi

c# - 如何在wpf treeview中显示所有直接和间接子成员的数量

转载 作者:太空宇宙 更新时间:2023-11-03 16:58:48 24 4
gpt4 key购买 nike

我有一个 WPF TreeView 控件,它以分层方式显示员工详细信息。我想显示员工姓名和他们直接和间接报告者的数量(例如,如果员工 C 向 B 报告,B 向A , 那么 A 的直接和间接 reportee 的数量将是 2)
但我能够显示直接报告者 (1) 的数量,但不能显示所有报告者 (2) 的数量。

我已经将数据库中的项目源绑定(bind)为列表(根):

我的xamal:

 <TreeView x:Name="tvMain" ItemsSource="{Binding Root}" BorderThickness="0">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Border BorderBrush="#02747474" Background="#02000000" HorizontalAlignment="Center" Margin="0,5,0,0" VerticalAlignment="Top" BorderThickness="1,1,1,1" x:Name="AvatarPhotoBorder">
<Border.BitmapEffect>
<DropShadowBitmapEffect ShadowDepth="7" Softness="0.75"/>
</Border.BitmapEffect>
<Image x:Name="imgPicture" Source="{Binding ImagePath}" Stretch="Uniform" VerticalAlignment="Top" Width="75" Height="60" HorizontalAlignment="Center" />
</Border>
<TextBlock VerticalAlignment="Center">
<TextBlock.Text>
<MultiBinding StringFormat=" {0} {1}">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
<TextBlock Text=" [Direct and Indirect reportee:" Foreground="LightGray" />
<TextBlock Text="{Binding Count}" Foreground="Gray" />??
<---- <TextBlock Text="{Binding Children.Count}"/>---->this will give only direct reportee count

<TextBlock Text="]" Foreground="LightGray" />
<StackPanel.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding IsSelected}" Value="true">
<Setter Property="StackPanel.Background" Value="LightBlue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
</StackPanel>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}" BasedOn="{StaticResource {x:Type TreeViewItem}}">
<Setter Property="IsExpanded" Value="True"/>
<Setter Property="IsSelected" Value="{Binding IsSelected}"/>
</Style>
</TreeView.ItemContainerStyle>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectedItemChanged">
<i:InvokeCommandAction Command="{Binding SelectedCommand}"
CommandParameter="{Binding ElementName=tvMain, Path=SelectedItem}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TreeView>
</StackPanel>

查看模型:

public class OrgElementViewModel : ViewModelBase
{
private int Id;
private string firstName;
private string lastName;
private string imagePath;
public int count;
private ObservableCollection<OrgElementViewModel> allchildren;

private ObservableCollection<OrgElementViewModel> children;

private bool isSelected;

public int Count
{
get { return GetAllChildren(); }
set { count = GetAllChildren(); }
}


private int GetAllChildren()
{


int dd =1;
allchildren = new ObservableCollection<OrgElementViewModel>();
//get the list of children from Model
foreach (Node i in OrgChartManager.Instance().GetAllChildren(this.ID))
{
//allchildren.Add(new OrgElementViewModel(i));

dd = dd + 1;
}

return dd;
}



public int ID
{
get { return Id; }
set { Id = value; }
}

public string FirstName
{
get { return firstName; }
set { firstName = value; }
}

public string LastName
{
get { return lastName; }
set { lastName = value; }
}

public string ImagePath
{
get { return imagePath; }
set { imagePath = value; }
}

public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
OnPropertyChanged("IsSelected");
}
}

public ObservableCollection<OrgElementViewModel> Children
{
get
{
if (children == null) //not yet initialized
return GetChildren();
return children;
}
set
{
children = value;
OnPropertyChanged("Children");
}
}

internal OrgElementViewModel(Node i)
{
this.ID = i.Id;
this.FirstName = i.FirstName;
this.LastName = i.LastName;
this.ImagePath = Path.GetFullPath("Images/" + this.ID.ToString() + ".png");



}

internal void ShowChildrenLevel(int levelsShown)

{
if (levelsShown == -1) //show all levels
this.Children = GetChildren();
else if (levelsShown == 0) //don't show any more levels
this.Children = new ObservableCollection<OrgElementViewModel>(); //set as empty
else if (levelsShown > 0) //if a level is requested
{
this.Children = GetChildren();

foreach (OrgElementViewModel i in this.Children)
i.ShowChildrenLevel(levelsShown - 1); //decrement 1 for next level
}
}

private ObservableCollection<OrgElementViewModel> GetChildren()
{
int dd =1;

children = new ObservableCollection<OrgElementViewModel>();
//get the list of children from Model
foreach (Node i in OrgChartManager.Instance().GetChildren(this.ID))
{
children.Add(new OrgElementViewModel(i));

}


return children;
}




}

其他类:

    public class OrgTreeViewModel : ViewModelBase
{
private static OrgTreeViewModel self;

private List<OrgElementViewModel> root;
private OrgElementViewModel selected;
private ICommand selectedCommand;
private ICommand changeDisplayLevelCommand;
private int count;
private int displayLevel = -1; //display all levels by default

//the root of the visual tree
public List<OrgElementViewModel> Root
{
get
{
if (root == null)
{
root = new List<OrgElementViewModel>();
root.Add(new OrgElementViewModel(OrgChartManager.Instance().GetRoot()));
}
return root;
}
}

public int Count
{
get { return count; }
set { count = GetCountOfEveryRecursiveObjects(Root, "Children");; }??
}



public OrgElementViewModel Selected
{
get { return selected; }
set
{
selected = value;
selected.IsSelected = true;
ShowChildrenLevel(); //show only the levels chosen by the user
OnPropertyChanged("Selected");
}
}

public ICommand SelectedCommand
{
get
{
if (selectedCommand == null)
{
selectedCommand = new CommandBase(i => this.SetSelected(i), null);
}
return selectedCommand;
}
}

public ICommand ChangeDisplayLevelCommand
{
get
{
if (changeDisplayLevelCommand == null)
{
changeDisplayLevelCommand = new CommandBase(i => ChangeDisplayLevel(i), null);
}
return changeDisplayLevelCommand;
}
}

private void SetSelected(object orgElement)
{
this.Selected = orgElement as OrgElementViewModel;
}

private void ChangeDisplayLevel(object i)
{
int level;
if (int.TryParse(i.ToString(), out level))
{
this.displayLevel = level;
ShowChildrenLevel(); //show only the levels chosen by the user
}
}

private void ShowChildrenLevel()
{
if (this.Selected != null)
{
this.Selected.ShowChildrenLevel(this.displayLevel);
}
}

private OrgTreeViewModel(){}

public static OrgTreeViewModel Instance()
{
if (self == null)
self = new OrgTreeViewModel();
return self;
}


public int GetCountOfEveryRecursiveObjects(IList list, string childrenPropertyName)
{
int count = list.Count;
foreach (object item in list)
{
System.Reflection.PropertyInfo property = item.GetType().GetProperty(childrenPropertyName);
IList childList = (IList)property.GetValue(item, null);??
if (childList == null)
continue;
count += GetCountOfEveryRecursiveObjects(childList, childrenPropertyName);
}
return count;
}




}

我的节点类:

    class Node
{
public int Id { get; set; }

public string FirstName { get; set; }

public string LastName { get; set; }

public int ParentId { get; set; }





}

我的模型:

 public   class OrgChartManager
{
private static OrgChartManager self;

//orgchart stored in dictionary
private Dictionary<int, Node> list = new Dictionary<int, Node>();

PersonalDAL dd = new PersonalDAL();


private OrgChartManager()
{

DataTable my_datatable = new DataTable();
my_datatable = new PersonalDAL().loademp();
int ColumnCount = my_datatable.Columns.Count;
int i = 1;
foreach (DataRow dr in my_datatable.Rows)
{
Node node = new Node
{
Id = (int)dr["ID"],
FirstName = (string)dr["FirstName"],
LastName = (string)dr["LastName"],
ParentId = (int)dr["ParentId"]

};
list.Add(i, node);
i++;
}


}

internal static OrgChartManager Instance()
{
if (self == null)
self = new OrgChartManager();
return self;
}

//get the root
internal Node GetRoot()
{
return list[1]; //return the top root node
}

//get the directchildren of a node
internal IEnumerable<Node> GetChildren(int parentId)
{
return from a in list
where a.Value.ParentId == parentId
&& a.Value.Id != parentId //don't include the root, which has the same Id and ParentId
select a.Value;


}
// Recursion method to get all the childeren under purcular ID
internal IEnumerable<Node> GetAllChildren(int parentId)
{
var result = new List<Node>();
var employees = from a in list
where (a.Value.ParentId == parentId
&& a.Value.Id != parentId) //don't include the root, which has the same Id and ParentId
select a.Value;

foreach (var employee in employees)
{
result.Add(employee);
result.AddRange(GetAllChildren(parentId));
}

return result;

}




}

我通过包含递归方法 (GetAllChildren) 修改了模型类。但是在运行此方法时会在行 result.AddRange(GetAllChildren(parentId)); 中抛出错误

最佳答案

如果我们认为您的树节点中有 Children 属性,我们可以使用此方法来计算所有 TreeView 项目:

    /// <summary>
/// get count of every recursive objects
/// </summary>
/// <param name="list">your list</param>
/// <param name="childrenPropertyName">your chil property</param>
/// <returns></returns>
public int GetCountOfEveryRecursiveObjects(IList list, string childrenPropertyName)
{
int count = list.Count;
foreach (object item in list)
{
System.Reflection.PropertyInfo property = item.GetType().GetProperty(childrenPropertyName);
IList childList = (IList)property.GetValue(item);
if (childList == null)
continue;
count += GetCountOfEveryRecursiveObjects(childList, childrenPropertyName);
}
return count;
}

测试:

int count = GetCountOfEveryRecursiveObjects((IList)tvMain.ItemsSource, "Children");

关于c# - 如何在wpf treeview中显示所有直接和间接子成员的数量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54169875/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com