I've been looking everywhere for proper documentation on the internet about the FrameworkElementFactory class, but I cannot seem to find proper tutorials or useful information on it.
Can someone that knows a bit more about this subject give me more information on it please? Here is what i've found so far from THIS question: (Thanks to Bob)
Bind the ItemsSource to myDataGrid:
Binding dataGridItemsSourceBinding = new Binding("MyItemsSourceName");
myDataGrid.SetBinding(DataGrid.ItemsSourceProperty, datagridItemsSourceBinding);
Create a DataGridTemplateColumn
DataGridTemplateColumn templatecolumn = new DataGridTemplateColumn() {
Header = "myColumnName", // Add the name of your column here
};
Create the Data Template for when you are displaying the value in the DataCell for the DataGrid Column
// Displaying Template for when you display the DataCell in the DataGridColumn
// Create a Data Template for when you are displaying a DataGridColumn
DataTemplate textBlockTemplate = new DataTemplate();
// Create a Framework Element for the DataGridColumn type (In this case, a TextBlock)
FrameworkElementFactory textBlockElement = new FrameworkElementFactory(typeof(TextBlock));
// Create a Binding to the value being displayed in the DataGridColumn
Binding textBlockBinding = new Binding("myPropertyName");
// Assign the Binding to the Text Property of the TextBlock
textBlockElement.SetBinding(TextBlock.TextProperty, textBlockBinding);
// Set the DataGridColumn to stretch to fit the text
textBlockElement.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
// Add the TextBlock element to the Visual Tree of the Data Template
textBlockTemplate.VisualTree = textBlockElement;
// Add the Data Template to the DataGridColumn Cell Template
templatecolumn.CellTemplate = textBlockTemplate;
Create the Data Template for when you are editing the value in the DataCell for the DataGrid Column
// Editing Template for when you edit the DataCell in the DataGridColumn
// Create a Data Template for when you are displaying a DataGridColumn
DataTemplate textBoxTemplate = new DataTemplate();
// Create a Framework Element for the DataGrid Column type (In this case, TextBox so the user can type)
FrameworkElementFactory textBoxElement = new FrameworkElementFactory(typeof(TextBox));
// Create a Binding to the value being edited in the DataGridColumn
Binding textBoxBinding = new Binding("myPropertyName");
// Assign the Binding to the Text Property of the TextBox
textBoxElement.SetBinding(TextBox.TextProperty, textBoxBinding);
// Set the DataGridColumn to stretch to fit the text
textBlockElement.SetValue(TextBlock.HorizontalAlignmentProperty, HorizontalAlignment.Stretch);
// Add the TextBox element to the Visual Tree of the Data Template
textBoxTemplate.VisualTree = textBoxElement;
// Add the Data Template to the DataGridColumn Cell Editing Template
templatecolumn.CellEditingTemplate = textBoxTemplate;
Add the completed DataGridColumn to your DataGrid
// Add the completed DataGridColumn to your DataGrid
myDataGrid.Columns.Add(templateColumn);
Please refer to this thread: Purpose of using FrameworkElementFactory
As for now Microsoft does not recommend using the FrameworkElementFactory
Related
I am creating and binding columns/elements into my datagrid.
I created a DataGridTemplateColumnand in that column i'm inserting a TextBox element.
DataGridTemplateColumn columnFeedbackSupplier = new DataGridTemplateColumn();
var dockPanel = new FrameworkElementFactory(typeof(DockPanel));
DataTemplate cellTemplate = new DataTemplate();
FrameworkElementFactory factoryText = new FrameworkElementFactory(typeof(TextBox));
Binding bindText = new Binding("Supplier");
bindText.Mode = BindingMode.TwoWay;
factoryText.SetValue(TextBox.TextProperty, bindText);
//This is not working
factoryText.SetValue(TextBox.VisibilityProperty, Visibility.Visible);
//
cellTemplate.VisualTree = factoryText;
dockPanel.AppendChild(factoryText);
cellTemplate.VisualTree = dockPanel;
Now when I add the following line, it allows me to edit my selected cell, but it also hides my TextBox on my datagrid until I double click on that cell then my element is visible again. Once that cell loses focus, my TextBox is hidden again.
columnFeedbackSupplier.CellEditingTemplate = cellTemplate;
I can use the following line to make my TextBox always visible, but I would not be able to save my edited values into my datagrid.
columnFeedbackSupplier.CellTemplate = cellTemplate;
Is there a way to make my TextBox always visible, while using CellEditingTemplate?
This part works.
In my C#.NET WPF XAML, I have a static ComboBox and a static TextBox. The TextBox displays another column from the same DataTable (in the ComboBox's ItemSource). The column "rr_code" is the column for company name and the column "rr_addr" is the column for the address.
<ComboBox x:Name="CompanyComboBox1" IsEditable="True" IsTextSearchEnabled="True" IsSynchronizedWithCurrentItem="False"/>
<TextBox x:Name="StreetTextBox1" DataContext="{Binding SelectedItem, ElementName=CompanyComboBox1}" Text="{Binding rr_addr}" IsManipulationEnabled="True"\>
The ComboBox reads programmatically from a column in a DataTable:
CompanyComboBox1.ItemsSource = Rails.DefaultView; // Rails is a DataTable
CompanyComboBox1.DisplayMemberPath = "rr_code"; // column name for company name
This part doesn't work
The question is, I now have a "Add Company" button that creates a new form in a StackPanel, dynamically and with this exact functionality. The ComboBox works exactly as expected. Here's what I have so far:
ComboBox companyComboBox = new ComboBox();
companyComboBox.ItemsSource = Rails.DefaultView;
companyComboBox.IsEditable = true;
companyComboBox.IsTextSearchEnabled = true;
companyComboBox.DisplayMemberPath = "rr_code";
The problem is in the TextBox, which is not updating when I change the dynamic companyComboBox, so I'm sure it has to do with the binding.
TextBox streetTextBox = new TextBox();
streetTextBox.DataContext = companyComboBox;
Binding b = new Binding("rr_addr");
b.Mode = BindingMode.Default;
b.Source = companyComboBox.SelectedItem;
streetTextBox.SetBinding(ComboBox.SelectedItemProperty, b);
What is the correct way to set the binding for the TextBox streetTextBox?
The code-behind equivalent of this particular XAML + C# data binding in pure C# is:
ComboBox companyComboBox = new ComboBox();
companyComboBox.ItemsSource = Rails.DefaultView; // Rails being DataTable
companyComboBox.IsEditable = true;
companyComboBox.IsTextSearchEnabled = true;
companyComboBox.DisplayMemberPath = "rr_code";
Binding b = new Binding("SelectedItem.rr_addr"); // The selected item's 'rr_addr' column ...
b.Source = companyComboBox; // ... of the companyComboBox ...
TextBox streetTextBox = new TextBox();
streetTextBox.SetBinding(TextBox.TextProperty,b); // ... is bound to streetTextBox's Text property.
The error was in the last line. SetBinding needed to have a property of the target, not the source. In addition, the Binding declaration needed "SelectedItem." for some reason.
Why are you setting the TextBox DataContext ?
You can simply bind TextBox.Text property to ComboBox SelectedItem in your XAML
<TextBox Text="{Binding ElementName=CompanyComboBox1, Path=SelectedItem.rr_addr}"></TextBox>
I need to copy a DataGrid removing the last column. I tried with this code and it sets the ItemSource correctly, but the columns are empty (in some case I bind object.property):
DataGrid dg = new DataGrid();
foreach (DataGridColumn dgColumns in source.Columns.Where(i => i.Header != "Sending Result"))
{
dg.Columns.Add(new DataGridTextColumn
{
Width = dgColumns.Width,
Header = dgColumns.Header,
Binding = new Binding(string.Format("{0}", dgColumns.SortMemberPath)));
}
}
dg.ItemsSource = source.ItemsSource;
Can anyone help me with this problem? Thank you in advance.
Your problem I think is that you are setting the ItemsSource property property before you are adding your grid into the logical tree.
Try adding the grid to its new parent, and then setting the ItemsSource.
This is my datagrid i want to display an image in the grid column but its is showing me text System.Windows.Media.Imaging.BitmapImage, instead of displaying an Image.
How to add an image in a datagrid column?
This is what I have tried :
Dictionary dict1=new Dictionary < string,object>();
string keyimage="Image";
object a1 = new BitmapImage();
a1=Imaging.CreateBitmapSourceFromHIcon(SystemIcons.Information.Handle, Int32Rect.Empty, null);
dict1.Add(keyimage, a1);
This dict1 serves as Itemsource for the datagrid...........how to make an image to be displayed in a datagrid column?
Make sure you use a DataGridTemplateColumn and put an image into it.
Since you are using a dictionary, bind the value, something like:
<Image Binding="{Binding Height="25" Width="50" Source="{Binding Value}" />
I suppose your Column datatype mismatches with itemsource datatype. You have to make equal datatype Image for both Grid Column and itemsource.
In my WPF project I made my column data template with Images:
DataTable dtab = new DataTable();
dtab.Columns.Add("imageColumn", typeof(BitmapImage));
//Uploading dtab with Images from DataBase
FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Image));
Binding bind = new System.Windows.Data.Binding("imageColumn");
factory.SetValue(Image.SourceProperty, bind);
DataTemplate cellTemplate = new DataTemplate() { VisualTree = factory };
DataGridTemplateColumn imgCol = new DataGridTemplateColumn()
{
Header="image",
CellTemplate = cellTemplate
};
DataGrid dg = new DataGrid();
dg.Columns.Add(imgCol);
dg.ItemsSource = dtab.DefaultView;
Hope this help
Add any image to your Project on Resource folder
After that try the below coding in DataGrid Bind event. Here i have add the image logo...
DataGridViewImageColumn imageColoumn = new DataGridViewImageColumn();
imageColoumn.HeaderText = "Img";
imageColoumn.Image = null;
imageColoumn.Name = "DataPic";
imageColoumn.Width = 150;
dataGridView1.Columns.Add(imageColoumn);
foreach (DataGridViewRow row in dataGridView1.Rows)
{
DataGridViewImageCell cell = row.Cells[1] as DataGridViewImageCell;
cell.Value = (System.Drawing.Image)Properties.Resources.logo;
}
I have a combobox control on form that pull its data (Displays and values) from some datasource. On another side I have table with one row. I want when app is lauching, combobox set selectedvalue or selecteditem to value of one column in above row. And when user has changed combobox it will persist change to row. I have tried to bind SelectedValue to this column, but it doesn't work. Combobox just sets on start to first item. What is problem?
EDIT
This is a Win Forms project.
Here is the binding code:
this.comboBoxCountries = new System.Windows.Forms.ComboBox();
this.countriesBindingSource = new System.Windows.Forms.BindingSource(this.components);
//
// comboBoxCountries
//
this.comboBoxCountries.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.searchCriteriaBindingSource, "Postcode", true));
this.comboBoxCountries.DataBindings.Add(new System.Windows.Forms.Binding("SelectedValue", this.searchCriteriaBindingSource, "CountryCode", true));
this.comboBoxCountries.DataSource = this.countriesBindingSource;
this.comboBoxCountries.DisplayMember = "Name";
this.comboBoxCountries.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.comboBoxCountries.FormattingEnabled = true;
this.comboBoxCountries.Location = new System.Drawing.Point(190, 19);
this.comboBoxCountries.Name = "comboBoxCountries";
this.comboBoxCountries.Size = new System.Drawing.Size(156, 21);
this.comboBoxCountries.TabIndex = 2;
this.comboBoxCountries.ValueMember = "Code";
this.comboBoxCountries.SelectedValueChanged += new System.EventHandler(this.comboBoxCountries_SelectedValueChanged);
//
// countriesBindingSource
//
this.countriesBindingSource.DataMember = "Countries";
this.countriesBindingSource.DataSource = this.dbDataSetCountries;
//
// dbDataSetCountries
//
this.dbDataSetCountries.DataSetName = "dbDataSetCountries";
this.dbDataSetCountries.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema;
//
// searchCriteriaBindingSource
//
this.searchCriteriaBindingSource.AllowNew = false;
this.searchCriteriaBindingSource.DataMember = "SearchCriteria";
this.searchCriteriaBindingSource.DataSource = this.dbDataSetSearchCriteria;
this.searchCriteriaBindingSource.BindingComplete += new System.Windows.Forms.BindingCompleteEventHandler(this.searchCriteriaBindingSource_BindingComplete);
//
// dbDataSetSearchCriteria
//
this.dbDataSetSearchCriteria.DataSetName = "dbDataSetSearchCriteria";
this.dbDataSetSearchCriteria.SchemaSerializationMode = System.Data.SchemaSerializationMode.IncludeSchema;
EDIT2
As I have mentioned in my comment below, I have another textbox that is binded to another DataMember of same binding source and textbox working fine. It's appear with appropriate value. When I change DataMember on same datamember on which I set selectedvalue property of combobox binding it's also show a good result and work properly.
Thanks in advance!
Take a look at the DisplayMember and ValueMember properties of the combobox. You need to tell the ComboBox what member from the datasource to display in the drop down, and what value to give when SelectedValue is requested.
It sounds like your ComboBox is bound to a static list while your rows are not. You might consider using a BindingSource that you set the ComboBox and the DataGridView's DataSource to. That way when the DGV navigates to a new row, the ComboBox will be updated with the value for the new row.
Here is a link to the ComboBox on MSDN: http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.aspx
I find it out. So for managing with this issue you should remove SelectedValue databinding from visual studio data bound menu and put an appropriate code to add this databinding in some place after filling all bindingsources:
private void MainForm_Load_1(object sender, EventArgs e)
{
this.searchCriteriaTableAdapter1.Fill(this.dbDataSetCountries.SearchCriteria);
this.searchCriteriaTableAdapter.Fill(this.dbDataSetSearchCriteria.SearchCriteria);
comboBoxCountries.DataBindings.Add("SelectedValue", this.dbDataSetCountries.SearchCriteria, "CountryCode");
}