当使用objectListView treeListView时,如果我已经扩展了treeListView并且点击了其中一列中的一个子节点,我该怎么做:
这个例子可能有助于解释我的意思。
public partial class Form1 : Form
{
List<Contract> list;
public Form1()
{
InitializeComponent();
list = new List<Contract>();
list.Add(new Contract("A", 1));
list.Add(new Contract("B", 2));
foreach (Contract c in list)
{
this.treeListView1.CanExpandGetter = delegate(object x)
{
if (x is Contract)
{
return (((Contract)x).Children.Count > 0);
}
else
{
return false;
}
};
this.treeListView1.ChildrenGetter = delegate(object x)
{
Contract contrat = x as Contract;
return contrat.Children;
};
column1.AspectGetter = delegate(object x)
{
if (x is Contract)
{
return ((Contract)x).Name;
}
else
{
return " ";
}
};
column2.AspectGetter = delegate(object x)
{
if (x is Contract)
{
return ((Contract)x).Value;
}
else
{
Double d = (Double)x;
return d.ToString();
}
};
this.treeListView1.AddObject(c);
}
}
private void treeListView1_CellClick(object sender, BrightIdeasSoftware.CellClickEventArgs e)
{
//NOT SURE WHAT TO DO HERE
}
public void WriteLine(String s)
{
if (this.richTextBox1.TextLength > 0)
{
this.richTextBox1.AppendText(Environment.NewLine);
}
this.richTextBox1.AppendText(s);
}
}
public class Contract
{
public string Name { get; set;}
public Double Value { get; set; }
public List<Double> Children {get; set;}
public Contract(string name, Double value)
{
Name = name;
Value = value;
Children = new List<Double>();
Children.Add(2);
Children.Add(3);
}
}
在CellClick事件中,我想获得父级和column1中父级的值。
答案 0 :(得分:2)
通过添加简单的double值作为子项,您自己做得有点困难。那些项目缺乏找到真正父母的潜力。
如果您能够更改Contract类,则可以将其更改为TreeNode类型,其子项始终引用合同本身。在cell_click上,您可以简单地获取e.Model,然后获取父级,以防它不是合约本身。
如果您希望它为将来要实现的实现更灵活,您可以更改契约,使其符合树结构
该界面表示您的节点有子节目
public interface ITreeNode
{
IList<ITreeChild> Children { get; }
}
一个表明它有父母
的界面public interface ITreeChild
{
object Parent { get; set; }
}
使childItems中的父引用保持最新的根节点
public abstract class TreeRoot : ITreeNode, IDisposable
{
private readonly IList<ITreeChild> children = new ObservableCollection<ITreeChild>();
public IList<ITreeChild> Children
{
get
{
return children;
}
}
protected virtual void OnChildCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.OldItems != null)
{
foreach (var item in e.OldItems)
{
var treeItem = item as ITreeChild;
if (treeItem == null)
{
continue;
}
treeItem.Parent = null;
}
}
if (e.NewItems != null)
{
foreach (var item in e.NewItems)
{
var treeItem = item as ITreeChild;
if (treeItem == null)
{
continue;
}
treeItem.Parent = this;
}
}
}
private bool isDisposed = false;
public virtual void Dispose(bool disposing)
{
if (!disposing)
{
return;
}
if (isDisposed)
{
return;
}
isDisposed = true;
Destroy();
}
public void Dispose()
{
Dispose(true);
}
public void Init()
{
var colc = Children as INotifyCollectionChanged;
if (colc != null)
{
colc.CollectionChanged += OnChildCollectionChanged;
}
}
public void Destroy()
{
Children.Clear();
var colc = Children as INotifyCollectionChanged;
if (colc != null)
{
colc.CollectionChanged -= OnChildCollectionChanged;
}
}
}
和基于此TreeRoot的TreeNode
public class TreeNode : TreeRoot, ITreeChild
{
public string Name
{
get;
set;
}
private object parent;
public object Parent
{
get
{
return parent;
}
set
{
parent = value;
}
}
public TreeNode()
: base()
{
Init();
}
}
一个非常基本的TreeChild(它更多地用作测试)
public class TreeChild : ITreeChild
{
public object Parent
{
get;set;
}
}
然后最终你的合同
public class Contract : TreeNode
{
public Double Value { get; set; }
public Contract()
: base()
{
}
}
可以包含所有类型的ITreeChild,因此将其设为DoubleChild
public class DoubleChild : TreeChild
{
private double value;
public double Value
{
get
{
return value;
}
set
{
this.value = value;
}
}
}
然后构建TreeListView:
protected void AddDefault(TreeNode c)
{
c.Children.Add(new DoubleChild { Value = 3 });
c.Children.Add(new DoubleChild { Value = 4 });
}
TreeListView treeListView1;
public Form1()
{
InitializeComponent();
treeListView1 = new TreeListView();
treeListView1.CellClick += treeListView1_CellClick;
OLVColumn columnName = new OLVColumn();
columnName.AspectGetter = (obj) =>
{
var node = obj as TreeNode;
if (node != null)
{
return node.Name;
}
return " ";
};
OLVColumn columnValue = new OLVColumn("Value", "Value");
treeListView1.Columns.Add(columnName);
treeListView1.Columns.Add(columnValue);
TreeNode rootContract = new TreeNode() { Name = "All Contracts" };
Contract childContract1 = new Contract() { Name = "A", Value = 2 };
Contract childContract2 = new Contract() { Name = "B", Value = 3 };
AddDefault(childContract1);
AddDefault(childContract2);
rootContract.Children.Add(childContract1);
rootContract.Children.Add(childContract2);
AddDefault(rootContract);
treeListView1.ParentGetter = (obj) =>
{
var child = obj as ITreeChild;
if (child == null)
{
return null;
}
return child.Parent;
};
treeListView1.ChildrenGetter = (obj) =>
{
var child = obj as ITreeNode;
if (child == null)
{
return null;
}
return child.Children;
};
treeListView1.CanExpandGetter = (obj) =>
{
return obj is ITreeNode && ((ITreeNode)obj).Children.Count > 0;
};
treeListView1.AddObject(rootContract);
treeListView1.Dock = DockStyle.Fill;
this.Controls.Add(treeListView1);
}
void treeListView1_CellClick(object sender, CellClickEventArgs e)
{
if (e.Model is Contract)
{
// you selected a contract
}
else
{
var tree = e.Model as ITreeChild;
var parent = tree.Parent;
if (parent is Contract)
{
// selected contract
}
else
{
// rootnode
}
}
}
我知道,它可能需要更多工作(我也可能有点复杂,不知道库),但这应该适合你的用例
答案 1 :(得分:2)
这是在VB.net,但我发现了一个非常简单的解决方案。只需调用treelistview.getparent事件即可。我的示例在格式行事件中显示它,但您也可以在选定的项事件中使用它。希望这有帮助
Private Sub TreeListView1_FormatRow(sender As Object, e As FormatRowEventArgs) Handles TreeListView1.FormatRow
Dim parent As myObjectExample = TreeListView1.GetParent(e.Model)
End Sub