Binding to dynamically created controls - wpf

I'm having trouble binding values to dynamically created controls. When a user loads a custom file and that file will have a unknown number of arguments. Arguments have a Group property that when grouped will dynamically add tabItems to a tabControl. I then loop through the arguments and add a label and, for now, a textbox to a grid inside the tabs. though i intend to use different controls depending on the arument type. I want to bind the argument Value property to the textbox. The tabs, labels and textboxes are added fine but, no value binding
He if my not yet re-factored solution so far;
myTab.Items.Clear();
var args = viewModel.Arguments;
var groups = args.GroupBy(arg => arg.Groups);
foreach (var group in groups)
{
TabItemExt tab = new TabItemExt();
tab.Header = group.Key;
Grid grid = new Grid();
grid.ColumnDefinitions.Add(new ColumnDefinition());
grid.ColumnDefinitions.Add(new ColumnDefinition());
int count = 0;
foreach (var argument in group)
{
RowDefinition newRow = new RowDefinition();
grid.RowDefinitions.Insert(count, newRow);
LabelTextBlock label = new LabelTextBlock();
label.Text = argument.DisplayName;
Grid.SetRow(label, count);
Grid.SetColumn(label, 0);
TextBox textBox = new TextBox();
var binding = new Binding();
binding.Source = viewModel.Arguments[argument.Name];
//binding.Source = argument
binding.Path = new PropertyPath("Value");
textBox.SetBinding(TextBlock.TextProperty, binding);
Grid.SetRow(textBox, count);
Grid.SetColumn(textBox, 1);
grid.Children.Add(label);
grid.Children.Add(textBox);
count += 1;
}
tab.Content = grid;
myTab.Items.Add(tab);
}

textBox.SetBinding(TextBlock.TextProperty, binding);
should have been
textBox.SetBinding(TextBox.TextProperty, binding);
just a little over dependent on intellisense.

Related

WPF dynamic DatagridComboboxColumn

I dynamically create a DataGridComboboxColum in the code. This works fine, however when I select an item in the Combobox in the Grid it disappears after i leave the combobox.
Here is the code:
MyDataGrid.ItemsSource = ergList;
DataGridComboBoxColumn cb = new DataGridComboBoxColumn();
cb.ItemsSource = data
cb.Header = "Tag";
cb.DisplayMemberPath = "Tag";
MyDataGrid.Columns.Add(cb);
How can i fix this?
You need to bind the selected value in the ComboBox to a property of the item in your ergList:
MyDataGrid.ItemsSource = ergList;
DataGridComboBoxColumn cb = new DataGridComboBoxColumn();
cb.ItemsSource = data
b.Header = "Tag";
cb.DisplayMemberPath = "Tag";
cb.SelectedValueBinding = new Binding("SomePropertyOfAnItemInErgList");
MyDataGrid.Columns.Add(cb);
Make sure that the types of the items in the ComboBox and the property to hold the selected value match.

trying to add listbox inside listboxitem in WPF

I am trying to use listbox inside listboxitem in WPF
Here , icTodoList and ActivityListBox are two main Lists. i want to add same number of lists in ActivityListBox as icTodoList and further i want to add one listbox under each listViewItem
The problem that is coming with this code is that it only binds listboxitem not listbox under wrap panel.
please let me know where i am wrong
for (var i = 0; i < icTodoList.Items.Count; i++)
{
ListBox lb = new ListBox();
ListBoxItem lbi = new ListBoxItem();
lb.Name = "InnerActivityList";
lb.Height = 500;
lb.Width = 225;
lb.Background = new SolidColorBrush(Colors.Red);
lbi.Content = lb;
ActivityListBox.Items.Add(lbi);
}

GTK CellRendererCombo set value into appropriate cell

What I'm trying to do it a TreeView that have several columns. The first column is a ComboBox, which means that I use Gtk.CellRendererCombo. The thing is, when I selected a value from the ComboBox, I'd like the Text from the cell to change from "" to the value I just selected. It feasible if at the Gtk.CellRendererCombo.Edited event I set the columns Text field to the EditedArgs.NewText.
The problem is, each time I set a value, I create a new row, and I'd like the Text Field to act like it does in the Gtk.CellRendererText, but it doesn't. It's not a different value for each row at that column, but the same value as setted in the Gtk.CellRendererCombo.Text
The Gtk.CellRenderer should not contain any state, so OK, using the Text field is a really bad idea from what I'm trying to do.
But if I set some value from the Gtk.ListStore that is the Model of my TreeView (Which is different from the Model for the Gtk.CellRendererCombo). The values setted will never show at the Column of the ComboBox.
class Program
{
private static Gtk.TreeView treeview = null;
static void OnEdited(object sender, Gtk.EditedArgs args)
{
Gtk.TreeSelection selection = treeview.Selection;
Gtk.TreeIter iter;
selection.GetSelected(out iter);
treeview.Model.SetValue(iter, 0, args.NewText); // the CellRendererCombo
treeview.Model.SetValue(iter, 1, args.NewText); // the CellRendererText
//(sender as Gtk.CellRendererCombo).Text = args.NewText; // Will set all the Cells of this Column to the Selection's Text
}
static void Main(string[] args)
{
Gtk.Application.Init();
Gtk.Window window = new Window("TreeView ComboTest");
window.WidthRequest = 200;
window.HeightRequest = 150;
Gtk.ListStore treeModel = new ListStore(typeof(string), typeof(string));
treeview = new TreeView(treeModel);
// Values to be chosen in the ComboBox
Gtk.ListStore comboModel = new ListStore(typeof(string));
Gtk.ComboBox comboBox = new ComboBox(comboModel);
comboBox.AppendText("<Please select>");
comboBox.AppendText("A");
comboBox.AppendText("B");
comboBox.AppendText("C");
comboBox.Active = 0;
Gtk.TreeViewColumn comboCol = new TreeViewColumn();
Gtk.CellRendererCombo comboCell = new CellRendererCombo();
comboCol.Title = "Combo Column";
comboCol.PackStart(comboCell, true);
comboCell.Editable = true;
comboCell.Edited += OnEdited;
comboCell.TextColumn = 0;
comboCell.Text = comboBox.ActiveText;
comboCell.Model = comboModel;
comboCell.WidthChars = 20;
Gtk.TreeViewColumn valueCol = new TreeViewColumn();
Gtk.CellRendererText valueCell = new CellRendererText();
valueCol.Title = "Value";
valueCol.PackStart(valueCell, true);
valueCol.AddAttribute(valueCell, "text", 1);
treeview.AppendColumn(comboCol);
treeview.AppendColumn(valueCol);
// Append the values used for the tests
treeModel.AppendValues("comboBox1", string.Empty); // the string value setted for the first column does not appear.
treeModel.AppendValues("comboBox2", string.Empty);
treeModel.AppendValues("comboBox3", string.Empty);
window.Add(treeview);
window.ShowAll();
Gtk.Application.Run();
}
}
I'd like the Cell of the ComboBox in which the selection has been made to show the value, but continue to be editable for later changes.
If someone has a way of doing this, I would be very grateful for you input. thanks.
Update:
What I think, because Gtk.CellRendererCombo inherits from Gtk.CellRendererText it just ignores the value setted in the cell. Now, I guess I could create a custom MyCellRendererCombo that inherits from Gtk.CellRendererCombo and use the value setted in the cell when supplied for the rendering, but the documentation on the difference between Gtk.CellRendererText and Gtk.CellRendererCombo is quite slim... I guess I should visit the implementation in C to know the details.
Ok, I've found a solution to my problem, I use a "hidden" column in which I read the "text" value. The hidden column contains the Gtk.CellRendererText, the Gtk.CellRendererCombo must have an Attribute Mapping with the new Column.
The resulting code is below:
class Program
{
private static Gtk.TreeView treeview = null;
static void OnEdited(object sender, Gtk.EditedArgs args)
{
Gtk.TreeSelection selection = treeview.Selection;
Gtk.TreeIter iter;
selection.GetSelected(out iter);
treeview.Model.SetValue(iter, 1, args.NewText); // the CellRendererText
}
static void Main(string[] args)
{
Gtk.Application.Init();
Gtk.Window window = new Window("TreeView ComboTest");
window.WidthRequest = 200;
window.HeightRequest = 150;
Gtk.ListStore treeModel = new ListStore(typeof(string), typeof(string));
treeview = new TreeView(treeModel);
// Values to be chosen in the ComboBox
Gtk.ListStore comboModel = new ListStore(typeof(string));
Gtk.ComboBox comboBox = new ComboBox(comboModel);
comboBox.AppendText("<Please select>");
comboBox.AppendText("A");
comboBox.AppendText("B");
comboBox.AppendText("C");
comboBox.Active = 0;
Gtk.TreeViewColumn comboCol = new TreeViewColumn();
Gtk.CellRendererCombo comboCell = new CellRendererCombo();
comboCol.Title = "Combo Column";
comboCol.PackStart(comboCell, true);
comboCol.AddAttribute(comboCell, "text", 1);
comboCell.Editable = true;
comboCell.Edited += OnEdited;
comboCell.TextColumn = 0;
comboCell.Text = comboBox.ActiveText;
comboCell.Model = comboModel;
comboCell.WidthChars = 20;
Gtk.TreeViewColumn valueCol = new TreeViewColumn();
Gtk.CellRendererText valueCell = new CellRendererText();
valueCol.Title = "Value";
valueCol.PackStart(valueCell, true);
valueCol.AddAttribute(valueCell, "text", 1);
valueCol.Visible = false;
treeview.AppendColumn(comboCol);
treeview.AppendColumn(valueCol);
// Append the values used for the tests
treeModel.AppendValues("comboBox1", "<Please select>"); // the string value setted for the first column does not appear.
treeModel.AppendValues("comboBox2", "<Please select>");
treeModel.AppendValues("comboBox3", "<Please select>");
window.Add(treeview);
window.ShowAll();
Gtk.Application.Run();
}
}

Combo Box in DataGrid WPF

I wanted a combo box in data grid which i added using the following code behind
DataColumn dc;
DataGridNS.DataGridTemplateColumn dgc = new DataGridNS.DataGridTemplateColumn();
dgc.Header = dc.ColumnName;
dgc.Width = 100;
dgc.IsReadOnly = true;
DataTemplate dtm = new DataTemplate();
FrameworkElementFactory outer = new FrameworkElementFactory(typeof(ComboBox));
dtm.VisualTree = outer;
dgc.CellTemplate = dtm;
dtgrdAtlas.Columns.Add(dgc);
i want to bind an array to this combo box.
how do i do that.
This code is in a seperate function where i add columns to data grid and my string array is in seperate function/class.
To bind a list to a ComboBox you need to set the ItemsSource, or Binding a List to the ItemsSource.
Here in this example I set directly the ItemsSource :
MyCombobox.ItemsSource = new List<int> {2, 3, 4 ,5, 6};

DataSet created in code not Binding to ListView

I have a WPF User Control with a ListView in it that is created based on the DataSet that is passed to it:
public void PopulateList(DataSet ds) {
listView.View = CreateGridViewColumns(ds.Tables[0]);
listData.DataContext = ds.Tables[0];
}
private GridView CreateGridViewColumns(DataTable dt) {
// Create the GridView
var gv = new GridView {AllowsColumnReorder = true};
// Create the GridView Columns
foreach (DataColumn item in dt.Columns) {
var gvc = new GridViewColumn
{
DisplayMemberBinding = new Binding(item.ColumnName),
Header = item.ColumnName,
Width = Double.NaN
};
gv.Columns.Add(gvc);
}
return gv;
}
Now I create the user control in code and call it's PopulateList with the appropriate dataset and this is where the problems are starting:
If I pass in a dataset that was created from a call to the database the list view shows all the data but if i pass in a DataSet that i created in code the ListView shows the Columns but will not show the data
//This is a function that hides the DB call return type is DataSet
var dsPatientSmokingStatusHistory = DataRepository.PatientSmokingStatusProvider.GetHistory(PatientId);
//radGridViewPatientSmokingStatus.DataSource = dsPatientSmokingStatusHistory.Tables[0];
var dt = new DataTable();
string c1 = "Date".PadLeft(23).PadRight(23);
string c2 = "Status".PadLeft(20).PadRight(50);
dt.Columns.Add(c1);
dt.Columns.Add(c2);
int i = 0;
foreach (DataRow row in dsPatientSmokingStatusHistory.Tables[0].Rows) {
var dataRow = dt.NewRow();
dataRow[c1] = ((DateTime)row["Date"]).ToString("MM/dd/yyyy");
dataRow[c2] = row["Status"].ToString();
dt.Rows.Add(dataRow);
dt.Rows[i].AcceptChanges();
i++;
}
DataSet ds = new DataSet();
dt.TableName = "Table";
ds.Tables.Add(dt);
ds.AcceptChanges();
smokingStatusGrid.GridWidth = 455;
smokingStatusGrid.GridHight = 97;
//This line does not show data
smokingStatusGrid.PopulateGrid(ds);
//This line will show data
smokingStatusGrid.PopulateGrid(dsPatientSmokingStatusHistory);
Is there a difference between these two datasets that i don't know about that is preventing me from databinding to it?
Also the user control is being used as an ElementHost in a WinForms application (not sure if this makes a difference)
Your code says:
DisplayMemberBinding = new Binding(item.ColumnName)
This binding constructor takes a string paramter which as per MSDN is "The initial Path for the binding" and is of datatype System.Windows.PropertyPath. I guess, since system tries to find a property with the same name in your class, and your string (item.ColumnName) has spaces at start, it runs into a problem (properties can't start with a space).
Would recommend you to take off the padding that you are doing in column name of your table. Apply any padding/margins in the Header of your GridView.

Resources