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");
Related
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;
}
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;
I've a DataGrid defined as follow:
private void CreateSemanticChannels()
{
myGrid.Style = (Style)FindResource("MyDataGrid");
var col1 = new DataGridTextColumn
{
Header = "FUNCTIONALITY",
Binding = new Binding("Functionality"),
};
myGrid.Columns.Add(col1);
var col2 = new DataGridTextColumn
{
Header = "ASSOCIATED TO",
Binding = new Binding("AssociatedTo"),
FontWeight = FontWeights.SemiBold
};
myGrid.Columns.Add(col2);
DataTemplate buttonTemplate = new DataTemplate();
FrameworkElementFactory buttonFactory = new FrameworkElementFactory(typeof(Button));
buttonTemplate.VisualTree = buttonFactory;
var col3 = new DataGridTemplateColumn
{
Header = "STATUS",
CellTemplate = buttonTemplate
};
myGrid.Columns.Add(col3);
// AGGIORNAMENTO CONTENUTO E VISUALIZZAZIONE
UpdateGrid();
myGrid.SelectedIndex = -1;
advSettingGrid.Children.Add(myGrid);
}
Where in UpdateGrid I add the item to the DataGrid.
myGrid.Items.Add(newRecord);
I want to modify the Style of each Button so I have started following this post but I have always ItemSource empty.
I read this, and actually I forgot to set the ItemSource property. So I defined the List of my object as _recordList and in the XAML I added this property
<Setter Property="BindingGroup" Value="{Binding Path=_recordList}"></Setter>
However, I still have ItemSource empty.
Any help is really appreciate!
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");
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} );