Evaluation support > Evaluation Questions
NodeControl binding
mark.robertson:
Hi
Working my way through getting familiar.
In my test app I am adding two of these NodeWithComboBox, each to show in column 1. Both are attached to the same parent node. Problem is I am getting two combo per node's column not just the one (the ComboBox object). I thought my visibility management within this sub-class would stop this happening....clearly it is not working.
Thanks for helping in advance.
Code: [Select]>>>> class NodeWithComboBox : BasicNode
{
public NodeComboBox ComboBox;
public int SelectedIndex = -1;
public NodeWithComboBox(Node pParentNode, int column, string title, string[] items, string value)
{
Text = title;
ComboBox = new NodeComboBox();
ComboBox.DataFieldName = "SelectedIndex";
ComboBox.EditStartMode = eEditStartMode.ClickOnSelected;
ComboBox.Editable = true;
ComboBox.InteractiveDropDownItems = true;
ComboBox.DropDownItems = items;
ComboBox.ColumnId = column;
ComboBox.VirtualMode = true;
Value = value;
AttachTo(pParentNode);
ComboBox.AttachTo(pParentNode.Treeview);
this.Treeview.NodeComboBoxGetItems += NodeComboBoxGetItems;
this.Treeview.FilterNodeControl += FilterNodeControl;
}
public string Value
{
get {
if (SelectedIndex >= ComboBox.DropDownItems.Count)
{
return "";
}
else
{
return ComboBox.DropDownItems[SelectedIndex].ToString();
}
}
set {
int ix = 0;
foreach (Object str in ComboBox.DropDownItems)
{
if (str.ToString() == value)
{
SelectedIndex = ix;
break;
}
ix++;
}
SelectedIndex = -1;
}
}
public new void FilterNodeControl(FlexibleTreeView pTreeview, FilterNodeControlEventArgs pArgs)
{
if (pArgs.NodeControl == this.ComboBox)
{
pArgs.ControlVisibility = eNodeControlVisibility.Visible;
}
}
private void NodeComboBoxGetItems(FlexibleTreeView pTreeview, NodeComboBoxGetItemsEventArgs pArgs)
{
if (pArgs.Node == this)
{
pArgs.Items = ComboBox.DropDownItems;
}
}
}
<<<<
mark.robertson:
Hi - I know the last method was inefficient (lots of controls created) and have been working at this. I have changed my constructor for the sub-class node to only create a new NodeComboBox if there is not one registered for this column. Code is below and I do not get the double controls now.
My question is ..... is there a better/more elegant method for doing this with core tree classes/objects? I really wish to create self-contained node classes that handle everything themselves and do not wish to mix node level code with code that has to create a tree and know what the nodes want (e.g. I know I could create every control type in every column or pre-plan and create what may be required in every column).
Thanks.
Code: [Select]>>>> class NodeWithComboBox : BasicNode
{
public int SelectedIndex = -1;
public string[] Items = { };
public int ColumnID = 0;
public Boolean Editable = false;
public NodeWithComboBox(Node pParentNode, int column, string title, string[] items, string value)
{
Text = title;
Boolean add = true;
foreach (NodeControl nc in pParentNode.Treeview.NodeControls)
{
if ((nc is NodeComboBox) && (nc.ColumnId == column))
{
add = false;
break;
}
}
if (add)
{
NodeComboBox newBox = new NodeComboBox();
newBox.DataFieldName = "SelectedIndex";
newBox.EditStartMode = eEditStartMode.ClickOnSelected;
newBox.Editable = true;
newBox.InteractiveDropDownItems = true;
newBox.ColumnId = column;
newBox.VirtualMode = true;
newBox.AttachTo(pParentNode.Treeview);
}
ColumnID = column;
Items = items;
Value = value;
AttachTo(pParentNode);
this.Treeview.NodeComboBoxGetItems += NodeComboBoxGetItems;
this.Treeview.FilterNodeControl += FilterNodeControl;
}
public string Value
{
get
{
if (SelectedIndex >= Items.Count())
{
return "";
}
else
{
return Items[SelectedIndex];
}
}
set
{
int ix = 0;
foreach (string str in Items)
{
if (str == value)
{
SelectedIndex = ix;
break;
}
ix++;
}
SelectedIndex = -1;
}
}
public new void FilterNodeControl(FlexibleTreeView pTreeview, FilterNodeControlEventArgs pArgs)
{
if ((pArgs.NodeControl.ColumnId == ColumnID) && (pArgs.NodeControl is NodeComboBox))
{
(pArgs.NodeControl as NodeComboBox).Editable = Editable;
pArgs.ControlVisibility = eNodeControlVisibility.Visible;
}
}
private void NodeComboBoxGetItems(FlexibleTreeView pTreeview, NodeComboBoxGetItemsEventArgs pArgs)
{
if (pArgs.Node == this)
{
pArgs.Items = Items;
}
}
}
<<<<
mark.robertson:
Hi
Now I have myself even more confused.
I created a new tree so that no others events were getting in the way. I then added one of my nodes (as below) which owns it controls and holds them in a List. I do not get any text or anything drawn and the GetValue event is called only for the Images never for the other controls.
What am I missing?
Thanks
Tree Construction
Code: [Select]>>>> treeView2 = new TreeViewWithImages();
treeView2.Parent = this.splitContainer1.Panel1;
treeView2.Bitmaps = null;
treeView2.AppendImageList(CommonImageList, CommonImageListNames);
treeView2.Dock = DockStyle.Fill;
treeView2.Columns.Clear();
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Options.Column.ShowVertLines = false;
treeView2.Options.NodeControl.DynamicColumnSpan = true;
treeView2.Options.NodeControl.NodeControlFilterMode = eNodeControlFilterMode.Dynamic;
BaudRateNode BR2 = new BaudRateNode(treeView2.Root);
BR2.Text = "BR2";
<<<<
Node
Code: [Select]>>>> class BaudRateNode : Node
{
public int SelectedIndex = -1;
//public string[] Items = { };
//public int ColumnID = 0;
public Boolean Editable = false;
public string s_Description = "description";
public string s_Text = "node";
public NodeImage TreeImage;
public NodeTextBox TreeText;
public NodeImage StatusImage;
public NodeComboBox BaudRate;
public NodeImage DescriptionImage;
public NodeTextBox Description;
List<NodeControl> Controls = new List<NodeControl>();
public BaudRateNode(Node pParentNode)
{
Text = "Baud Rate";
AttachTo(pParentNode);
TreeImage = new NodeImage();
TreeImage.AttachTo(pParentNode.Treeview);
TreeImage.ColumnId = 3;
TreeImage.VirtualMode = true;
TreeImage.FillFreeSpace = true;
TreeText = new NodeTextBox();
TreeText.AttachTo(pParentNode.Treeview);
//TreeText.DataFieldName = "s_Text";
TreeText.ColumnId = 3;
TreeText.VirtualMode = true;
TreeText.FillFreeSpace = true;
StatusImage = new NodeImage();
StatusImage.AttachTo(pParentNode.Treeview);
StatusImage.ColumnId = 4;
StatusImage.ContentAlign = ContentAlignment.MiddleCenter;
StatusImage.VirtualMode = true;
StatusImage.FillFreeSpace = true;
BaudRate = new NodeComboBox();
BaudRate.AttachTo(pParentNode.Treeview);
BaudRate.ColumnId = 5;
BaudRate.DataFieldName = "SelectedIndex";
BaudRate.EditStartMode = eEditStartMode.ClickOnSelected;
BaudRate.Editable = true;
//BaudRate.InteractiveDropDownItems = true;
BaudRate.VirtualMode = true;
BaudRate.FillFreeSpace = true;
BaudRate.DropDownItems = new string[] { "19200", "38400", "57600" };
DescriptionImage = new NodeImage();
DescriptionImage.AttachTo(pParentNode.Treeview);
DescriptionImage.ColumnId = 6;
DescriptionImage.ContentAlign = ContentAlignment.MiddleCenter;
DescriptionImage.VirtualMode = true;
DescriptionImage.FillFreeSpace = true;
Description = new NodeTextBox();
Description.AttachTo(pParentNode.Treeview);
Description.DataFieldName = "s_Description";
Description.ColumnId = 6;
Description.VirtualMode = true;
Description.FillFreeSpace = true;
Controls.Add(TreeImage);
Controls.Add(TreeText);
Controls.Add(StatusImage);
Controls.Add(BaudRate);
Controls.Add(DescriptionImage);
Controls.Add(Description);
//ColumnID = column;
//Value = value;
this.Treeview.NodeComboBoxGetItems += NodeComboBoxGetItems;
this.Treeview.FilterNodeControl += FilterNodeControl;
this.Treeview.NodeEditing += NodeEditing;
this.Treeview.NodeControlValueGet += NodeControlValueGet;
}
bool NodeControlValueGet(FlexibleTreeView pTreeview, NodeControlValueEventArgs pArgs)
{
if ((pArgs.Node == this) && Controls.Contains(pArgs.NodeControl))
{
if (pArgs.NodeControl == TreeText)
{
pArgs.Value = "test";
}
else if (pArgs.NodeControl == BaudRate)
{
pArgs.Value = "19200";
}
else if (pArgs.NodeControl == Description)
{
pArgs.Value = "Hello";
}
return true;
}
return false;
}
public string Value
{
get
{
if ((SelectedIndex < 0) || (SelectedIndex >= BaudRate.DropDownItems.Count))
{
return "";
}
else
{
return BaudRate.DropDownItems[SelectedIndex].ToString();
}
}
set
{
int ix = 0;
foreach (string str in BaudRate.DropDownItems)
{
if (str == value)
{
SelectedIndex = ix;
return;
}
ix++;
}
SelectedIndex = -1;
}
}
public void FilterNodeControl(FlexibleTreeView pTreeview, FilterNodeControlEventArgs pArgs)
{
if (pArgs.Node == this)
{
pArgs.ControlVisibility = Controls.Contains(pArgs.NodeControl) ? eNodeControlVisibility.Visible : eNodeControlVisibility.Hidden;
}
}
private void NodeComboBoxGetItems(FlexibleTreeView pTreeview, NodeComboBoxGetItemsEventArgs pArgs)
{
if (pArgs.Node == this)
{
pArgs.Items = BaudRate.DropDownItems;
}
}
private void NodeEditing(FlexibleTreeView pTreeview, NodeEditingEventArgs pArgs)
{
if (pArgs.Node == this)
{
pArgs.Cancel = !Editable;
}
}
}<<<<
mark.robertson:
Hi
Final revision as I am more clear now on what I need solved. Code is below.
1. I create a tree with columns
2. I create a node which has multiple controls
3. If I put each control in its own column it works
4. if I put two controls in the same column I only get one control - the first control in that column attached to the tree
If you can help me solve this problem (4) then I have a good starting point and can see how to create nodes that manage themselves.
Tree Create
Code: [Select]>>>> treeView2 = new TreeViewWithImages();
treeView2.Parent = this.splitContainer1.Panel1;
treeView2.Bitmaps = null;
treeView2.AppendImageList(CommonImageList, CommonImageListNames);
treeView2.Dock = DockStyle.Fill;
treeView2.Columns.Clear();
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Columns.Add(new ARMSoft.FlexibleTreeView.Column.TreeColumn());
treeView2.Options.Column.ShowVertLines = false;
treeView2.Options.NodeControl.DynamicColumnSpan = true;
treeView2.Options.NodeControl.NodeControlFilterMode = eNodeControlFilterMode.Dynamic;
BaudRateNode BR2 = new BaudRateNode(treeView2.Root);
BR2.Text = "BR2";
<<<<
Node
Code: [Select]>>>> class BaudRateNode : Node
{
public int SelectedIndex = -1;
//public string[] Items = { };
//public int ColumnID = 0;
public Boolean Editable = true;
public string s_Description = "description";
public string s_Text = "node";
public NodeImage TreeImage;
public NodeTextBox TreeText;
public NodeImage StatusImage;
public NodeComboBox BaudRate;
public NodeImage DescriptionImage;
public NodeTextBox Description;
List<NodeControl> Controls = new List<NodeControl>();
public BaudRateNode(Node pParentNode)
{
Text = "Baud Rate";
AttachTo(pParentNode);
TreeImage = new NodeImage();
TreeImage.AttachTo(pParentNode.Treeview);
TreeImage.ColumnId = 1;
TreeImage.VirtualMode = true;
TreeImage.FillFreeSpace = true;
TreeText = new NodeTextBox();
TreeText.AttachTo(pParentNode.Treeview);
TreeText.ColumnId = 1;
TreeText.VirtualMode = true;
TreeText.FillFreeSpace = true;
StatusImage = new NodeImage();
StatusImage.AttachTo(pParentNode.Treeview);
StatusImage.ColumnId = 3;
StatusImage.ContentAlign = ContentAlignment.MiddleCenter;
StatusImage.VirtualMode = true;
StatusImage.FillFreeSpace = true;
BaudRate = new NodeComboBox();
BaudRate.AttachTo(pParentNode.Treeview);
BaudRate.ColumnId = 4;
//BaudRate.DataFieldName = "SelectedIndex";
BaudRate.EditStartMode = eEditStartMode.ClickOnSelected;
BaudRate.Editable = true;
//BaudRate.InteractiveDropDownItems = true;
BaudRate.VirtualMode = true;
BaudRate.FillFreeSpace = true;
BaudRate.DropDownItems = new string[] { "19200", "38400", "57600" };
DescriptionImage = new NodeImage();
DescriptionImage.AttachTo(pParentNode.Treeview);
DescriptionImage.ColumnId = 5;
DescriptionImage.ContentAlign = ContentAlignment.MiddleCenter;
DescriptionImage.VirtualMode = true;
DescriptionImage.FillFreeSpace = true;
Description = new NodeTextBox();
Description.AttachTo(pParentNode.Treeview);
Description.DataFieldName = "s_Description";
Description.ColumnId = 6;
Description.VirtualMode = true;
Description.FillFreeSpace = true;
Controls.Add(TreeImage);
Controls.Add(TreeText);
Controls.Add(StatusImage);
Controls.Add(BaudRate);
Controls.Add(DescriptionImage);
Controls.Add(Description);
//ColumnID = column;
//Value = value;
this.Treeview.NodeComboBoxGetItems += NodeComboBoxGetItems;
this.Treeview.FilterNodeControl += FilterNodeControl;
this.Treeview.NodeEditing += NodeEditing;
this.Treeview.NodeControlValueGet += NodeControlValueGet;
}
bool NodeControlValueGet(FlexibleTreeView pTreeview, NodeControlValueEventArgs pArgs)
{
if ((pArgs.Node == this) && Controls.Contains(pArgs.NodeControl))
{
if (pArgs.NodeControl == TreeText)
{
pArgs.Value = "test";
return true;
}
else if (pArgs.NodeControl == BaudRate)
{
pArgs.Value = 0;
return true;
}
else if (pArgs.NodeControl == Description)
{
pArgs.Value = "Hello";
return true;
}
else if (pArgs.NodeControl == TreeImage)
{
pArgs.Value = (pTreeview as TreeViewWithImages).Bitmaps["folder_open"];
return true;
}
else if (pArgs.NodeControl == StatusImage)
{
pArgs.Value = (pTreeview as TreeViewWithImages).Bitmaps["folder_open"];
return true;
}
else if (pArgs.NodeControl == DescriptionImage)
{
pArgs.Value = (pTreeview as TreeViewWithImages).Bitmaps["folder_closed"];
return true;
}
}
return false;
}
public string Value
{
get
{
if ((SelectedIndex < 0) || (SelectedIndex >= BaudRate.DropDownItems.Count))
{
return "";
}
else
{
return BaudRate.DropDownItems[SelectedIndex].ToString();
}
}
set
{
int ix = 0;
foreach (string str in BaudRate.DropDownItems)
{
if (str == value)
{
SelectedIndex = ix;
return;
}
ix++;
}
SelectedIndex = -1;
}
}
public void FilterNodeControl(FlexibleTreeView pTreeview, FilterNodeControlEventArgs pArgs)
{
if (pArgs.Node == this)
{
pArgs.ControlVisibility = Controls.Contains(pArgs.NodeControl) ? eNodeControlVisibility.Visible : eNodeControlVisibility.Hidden;
}
}
private void NodeComboBoxGetItems(FlexibleTreeView pTreeview, NodeComboBoxGetItemsEventArgs pArgs)
{
if (pArgs.Node == this)
{
pArgs.Items = BaudRate.DropDownItems;
}
}
private void NodeEditing(FlexibleTreeView pTreeview, NodeEditingEventArgs pArgs)
{
if (pArgs.Node == this)
{
pArgs.Cancel = !Editable;
}
}
}
<<<<
Ruslan:
Regarding your last message:
1) don`t mix node controls creation with node logic, it`s very bad practise and may lead to visual issues (multiple of the same node controls appear in the tree because every added node create and add to the treeview new banch of such node controls). Instead, move all logic regarding node controls creation or node controls` events handling from the BaudRateNode`s .ctor to separate class and call this logic only once after creation of the treeview.
2) You see only first node control because you`ve enabled FillFreeSpace for all node controls. When it is enabled, this particular node control fill all available free space within column from his start location to right end, so you won`t see any other controls because this, first, control grabs all available space. To fix it remove FillFreeSpace=true line for all node controls.
Navigation
[0] Message Index
[#] Next page