Datatemplate in c# code-behind - c#

I search an option to build a datatemplate in c# code.
I had used :
DataTemplate dt = new DataTemplate(typeof(TextBox));
Binding bind = new Binding();
bind.Path = new PropertyPath("Text");
bind.Mode = BindingMode.TwoWay;
FrameworkElementFactory txtElement = new FrameworkElementFactory(typeof(TextBox));
txtElement.SetBinding(TextBox.TextProperty, bind);
txtElement.SetValue(TextBox.TextProperty, "test");
dt.VisualTree = txtElement;
textBox1.Resources.Add(dt, null);
But it doesn't work (it is placed at the Loaded-Method of the window - so my textbox should show the word "test" at window start). Any idea?

Each element needs to be added to the current visual tree. For example:
ListView parentElement; // For example a ListView
// First: create and add the data template to the parent control
DataTemplate dt = new DataTemplate(typeof(TextBox));
parentElement.ItemTemplate = dt;
// Second: create and add the text box to the data template
FrameworkElementFactory txtElement =
new FrameworkElementFactory(typeof(TextBox));
dt.VisualTree = txtElement;
// Create binding
Binding bind = new Binding();
bind.Path = new PropertyPath("Text");
bind.Mode = BindingMode.TwoWay;
// Third: set the binding in the text box
txtElement.SetBinding(TextBox.TextProperty, bind);
txtElement.SetValue(TextBox.TextProperty, "test");

Related

How to dynamically create data template and bind treeview hierarchical data in code behind C#

I have a scenario, where a treeview changes its data template and data binding definition dynamically.
I created a treeview in XAML like this:
<TreeView x:Name="BimTreeView">
</TreeView>
I didn't defined the data template and binding definition in XAML. Because the data template and binding definition must have to be changed by user's preference.
I tried the following C# code that I found here to create the data template definition dynamically. However, looking at the following code, I couldn't figure out how to change data binding definition via C# code.
private DataTemplate GetHeaderTemplate()
{
//create the data template
DataTemplate dataTemplate = new DataTemplate();
//create stack pane;
FrameworkElementFactory stackPanel = new FrameworkElementFactory(typeof(StackPanel));
stackPanel.Name = "parentStackpanel";
stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
// Create check box
FrameworkElementFactory checkBox = new FrameworkElementFactory(typeof(CheckBox));
checkBox.Name = "chk";
checkBox.SetValue(CheckBox.NameProperty, "chk");
checkBox.SetValue(CheckBox.TagProperty, new Binding());
checkBox.SetValue(CheckBox.MarginProperty, new Thickness(2));
checkBox.SetValue(CheckBox.TagProperty, new Binding() { Path = new PropertyPath("Name") });
stackPanel.AppendChild(checkBox);
// Create Image
FrameworkElementFactory image = new FrameworkElementFactory(typeof(Image));
image.SetValue(Image.MarginProperty, new Thickness(2));
image.SetBinding(Image.SourceProperty, new Binding() { Path = new PropertyPath("ImageUrl") });
stackPanel.AppendChild(image);
// create text
FrameworkElementFactory label = new FrameworkElementFactory(typeof(TextBlock));
label.SetBinding(TextBlock.TextProperty, new Binding() { Path = new PropertyPath("Name") });
label.SetValue(TextBlock.ToolTipProperty, new Binding());
stackPanel.AppendChild(label);
//set the visual tree of the data template
dataTemplate.VisualTree = stackPanel;
return dataTemplate;
}
I would really appreciate if someone could explain how can I change the data template and bind treeview hierarchical data in code behind C#.
Thank you!!
Here's the remedy to the above code. The following code can now dynamically bind and can dynamically create datatemplate for the treeview in wpf.
public static void FillTree()
{
BIMExplorerUserControl.Instance.BimTreeView.ItemTemplate = GetTemplate();
BIMExplorerUserControl.Instance.BimTreeView.ItemsSource = ViewModel.Instance.DefaultExplorerView;
}
public static HierarchicalDataTemplate GetTemplate()
{
//create the data template
HierarchicalDataTemplate dataTemplate = new HierarchicalDataTemplate();
//create stack pane;
FrameworkElementFactory stackPanel = new FrameworkElementFactory(typeof(StackPanel));
stackPanel.Name = "parentStackpanel";
stackPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);
////// Create check box
FrameworkElementFactory checkBox = new FrameworkElementFactory(typeof(CheckBox));
checkBox.Name = "chk";
checkBox.SetValue(CheckBox.NameProperty, "chk");
checkBox.SetValue(CheckBox.TagProperty, new Binding());
checkBox.SetValue(CheckBox.MarginProperty, new Thickness(2));
checkBox.SetValue(CheckBox.TagProperty, new Binding() { Path = new PropertyPath("Name") });
stackPanel.AppendChild(checkBox);
// create text
FrameworkElementFactory label = new FrameworkElementFactory(typeof(TextBlock));
label.SetBinding(TextBlock.TextProperty, new Binding() { Path = new PropertyPath("Name") });
label.SetValue(TextBlock.MarginProperty, new Thickness(2));
label.SetValue(TextBlock.FontWeightProperty, FontWeights.Bold);
label.SetValue(TextBlock.ToolTipProperty, new Binding());
stackPanel.AppendChild(label);
dataTemplate.ItemsSource = new Binding("Elements");
//set the visual tree of the data template
dataTemplate.VisualTree = stackPanel;
return dataTemplate;
}

Combobox in TemplateColumn fill RowHeight

I create my DataGridTemplateColumn with a ComboBox inside in my Code. When I change the Height of my DataGridRow I want the ComboBox to always fill the Cell. But as it is now my ComboBox always stays the same Height. It works with the Width though. Here is what I have tried so far:
(For Information the whole code)
ItemsPanelTemplate IPT = null;
DataGridTemplateColumn DGTC = new DataGridTemplateColumn();
DataTemplate DataTMP = null;
Binding bind = new Binding(strPropertyname);
FrameworkElementFactory cboFactory = new FrameworkElementFactory(typeof(ComboBox));
cboFactory.SetValue(ComboBox.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
cboFactory.SetValue(ComboBox.VerticalAlignmentProperty, VerticalAlignment.Stretch);
cboFactory.SetValue(ComboBox.ItemsSourceProperty, DTCBOSource.DefaultView);
cboFactory.SetValue(ComboBox.IsEditableProperty, false);
cboFactory.SetValue(ComboBox.IsTextSearchEnabledProperty, true);
cboFactory.SetValue(ComboBox.IsEnabledProperty, !blnIsReadOnly);
cboFactory.SetValue(ComboBox.SelectedValuePathProperty, DTCBOSource.Columns[0].ColumnName);
cboFactory.SetValue(ComboBox.DisplayMemberPathProperty, DTCBOSource.Columns[1].ColumnName);
Binding bHeight = new Binding();
bHeight.Source = _DGSource;
bHeight.Path = new PropertyPath("RowHeight");
bHeight.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
cboFactory.SetValue(ComboBox.HeightProperty, bHeight);
cboFactory.AddHandler(ComboBox.GotFocusEvent, new RoutedEventHandler(DG_EditingElementEnter));
cboFactory.AddHandler(ComboBox.LostFocusEvent, new RoutedEventHandler(DG_EditingElementLeave));
IPT = (ItemsPanelTemplate)(Application.Current.TryFindResource("CBOVirtualPanel"));
if (IPT != null)
{
cboFactory.SetValue(ComboBox.ItemsPanelProperty, IPT);
}
bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
bind.NotifyOnTargetUpdated = true;
//bind.Mode = BindingMode.TwoWay;
cboFactory.SetBinding(ComboBox.SelectedValueProperty, bind);
DataTMP = new DataTemplate();
DataTMP.VisualTree = cboFactory;
DGTC.CellTemplate = DataTMP;
DGTC.SortMemberPath = strPropertyname;
//_DGSource.TargetUpdated += DG_CellValueChanged_Event;
return DGTC;

WPF Datagrid Combox editable

My goal it's to put a ComboBox editable in a DataGrid, for that I put a TextBlock in CellTemplate and a ComboBox in CellEditingTemplate. But how bind my TextBlock with the text of selected item in ComboBox ?
var textBlockFactory = new FrameworkElementFactory(typeof(TextBlock));
textBlockFactory.SetBinding(TextBlock.TextProperty, new Binding("Description"));
dgc.ClipboardContentBinding = new Binding("Description");
var template = new DataTemplate();
template.VisualTree = textBlockFactory;
dgc.CellTemplate = template;
var comboBoxFactory = new FrameworkElementFactory(typeof(ComboBox));
template = new DataTemplate();
template.VisualTree = comboBoxFactory;
Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, typeof(UserControl), 1);
b.Path = new PropertyPath(BindingList);
comboBoxFactory.SetBinding(ComboBox.ItemsSourceProperty, b);
comboBoxFactory.SetValue(ComboBox.IsEditableProperty, true);
comboBoxFactory.SetValue(ComboBox.SelectedValueProperty, new Binding("Type"));
comboBoxFactory.SetValue(ComboBox.SelectedValuePathProperty, "Id");
comboBoxFactory.SetValue(ComboBox.DisplayMemberPathProperty, "Description");
dgc.CellEditingTemplate = template;
dgc.SortMemberPath = BindingCurrentItem;
In this particular scenario, you will have to make one more property say SelectedBinding in your model backing your DataGridItem. The type of property should be of type of item in your BindingList.
Then you can bind the SelectedItem of your ComboBox to it as
comboBoxFactory.SetValue(ComboBox.SelectedItemProperty, new Binding("SelectedBinding"));
and you can update your TextBlock binding as
dgc.ClipboardContentBinding = new Binding("SelectedBinding.Description");

WPF Binding TextBox and DataRow in code

I want to bind TextBox and column of datarow but doesn't work.
My code:
// Member is a DataRow
for(int i=0;i<Member.Table.Count;++i)
{
TextBox textbox = TextBox();
textbox.Text = Member.Field<string>(i);
Binding binding = new Binding(Member.Table.Columns[i].ColumnName);
binding.Source = Member;
binding.Path = new PropertyPath(Member.Table.Columns[i].ColumnName);
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.Mode = BindingMode.TwoWay;
textbox.SetBinding(System.Windows.Controls.TextBox.TextProperty, binding);
}
Any idea?
Thinks
you are creating the textbox in your code, but never showing it anywhere so it may be working but you will never see the results.

Databinding the DataGrid column header in code

How do I databind a WPF Toolkit DataGrid column header value in code (not XAML)?
DataGridColumn fooColumn = new DataGridTextColumn
{
Header = "Foo",
Binding = new Binding {Path = new PropertyPath("BindingPath"),
Mode = BindingMode.OneWay}
};
This databinds the content of the cells of the column. But how do I databind the header text ("Foo") itself (to, say, a string property on a viewmodel)?
DataGridColumn fooColumn = new DataGridTextColumn
{
Binding = new Binding {Path = new PropertyPath("BindingPath"),
Mode = BindingMode.OneWay}
};
BindingOperations.SetBinding(fooColumn, DataGridColumn.HeaderProperty, new Binding("Foo") { Source = yourViewModel} );

Categories