Do this in C# code instead of template XAML - silverlight

Is there a way to make column of cells in a Silverlight datagrid be readonly in editmode with C# code instead of setting up a entire datagrid as a template in a resource file?
UPDATE
Found an example piece of code -
http://forums.silverlight.net/forums/p/17483/58189.aspx
In the response by slhungry midway into the thread. He has example code written as a XAML template. Can you write this in C#?

Well, you can certainly create DataGridColumns programmatically in your codebehind and add them to your DataGrid:
DataGridColumn myColumn = new DataGridColumn();
Then you can easily configure the properties:
myColumn.Header = "tyndall's New Column";
myColumn.IsReadOnly = true; // All cells in column will be readonly
You can also programmatically set up binding in the codebehind, if you wish. Finally, you can add this column to the datagrid:
myDataGrid.Columns.Add(myColumn);
Does this help answer your question?

Related

Setting wpf DataGrid Column style programatically - After a 'SetterBaseCollection' is in use (sealed), it cannot be modified

I am changing my DataGrid's column colors programmatically with the following code:
this.ImportPreview.Columns[index].CellStyle = new Style(typeof(DataGridCell));
this.ImportPreview.Columns[index].CellStyle.Setters.Add(new Setter(DataGridCell.BackgroundProperty, new SolidColorBrush(Colors.LightBlue)));
This works one single time for each column. If I try to change it a second time, the Setter Collection is locked.
The following Error appears:
System.InvalidOperationException:
'After a 'SetterBaseCollection' is in use (sealed), it cannot be modified.'
I tried clearing the setter collection with the same result:
this.ImportPreview.Columns[index].CellStyle.Setters.Clear();
I found the following Promising question/answer, but the answer is to shorthanded for me. I do not know how to apply this Answer:
How to add further style setters programmatically? When I try I got an InvalidOperationException exception (SetterBaseCollection is in use)
additionally there are a lot of similar questions but they are based around setting the style in xaml whereas I am trying to do it programmatically.
Instead of adding setters to an existing Style, you should create a new Style and set the CellStyle property to this one.
You may base the new Style on the existing one and then simply add the additional setters. Something like this:
DataGridColumn column = this.ImportPreview.Columns[index];
Style newCellStyle = new Style(typeof(DataGridCell), column.CellStyle);
newCellStyle.Setters.Add(new Setter(DataGridCell.BackgroundProperty, new SolidColorBrush(Colors.LightBlue)));
column.CellStyle = newCellStyle;

WPF Datagrid Button commandParameter in code behind

I'm trying to build a datagrid with columns and a button in code behind and I want to assign the command parameter of this button to the value of the "ID" column which is "TDENT_ID". Here's my code
this line is not working as you can see :
BtnDetail.SetBinding(System.Windows.Controls.Primitives.ButtonBase.CommandParameterProperty, new Binding() { Source = dtGrid, Path = "TDENT_ID" });
How can I write it?
FrameworkElementFactory:
"This class is a deprecated way to programmatically create templates, which are subclasses of FrameworkTemplate such as ControlTemplate or DataTemplate; not all of the template functionality is available when you create a template using this class. The recommended way to programmatically create a template is to load XAML from a string or a memory stream using the Load method of the XamlReader class." Microsoft Docs
Your Bindingis wrong. It currently points to the DataGrid which does not have a property TDENT_ID.
This property is on your data item, which is the DataContext of the column's template.
Therefore, correct Binding would be:
// Set up a Binding that uses the current DataContext as Binding.Source
BtnDetail.SetBinding(ButtonBase.CommandParameterProperty, new Binding(nameof(myItemType.TDENT_ID)));
Microsoft Docs: Specifying the binding source
Try to learn XAML. It makes writing such UI related code much easier, which makes you more productive.

Add columns and rows to wpf listview dynamically

i want to add new columns and rows to a C# WPF ListView (GridView) at runtime. As far as i know you can only add rows to a gridview by using anonymous objects or classes with a static set of members to which the columns are bound. Is there a way to do this at runtime that the user is able to add a new column, bind this column to something and add new data?
thx
ooorndtski
Yes, you can do this in code an runtime. You need the GridView as a variable (give it a name in XAML to auto-generate that variable in Visual Studio). The GridView has a Columns property that you can handle like any other collection, you can add and remove for example.
This is the example from MSDN (The gridview name "myGridView"):
GridViewColumn gvc3 = new GridViewColumn();
gvc3.DisplayMemberBinding = new Binding("EmployeeNumber");
gvc3.Header = "Employee No.";
gvc3.Width = 100;
myGridView.Columns.Add(gvc3);
Generally speaking, anything you can do in XAML, you can do in code.
So, what i was looking for is described in this thread.
He creates a new Dictionary-class, which implements the INotifyPropertyChanged interface.
When adding data to the dictionary an event is triggered.
At the place in your code where you want to add a new row, you just put the data into an object of this Dictionary class and add the Dictionary to an ObservableCollection which is bound to the DataGrid.

WPF: New Row on Datagrid that bind to custom class

I created some custom data container class with OnPropertyChanged event and ObservableCollection and bind it to datagrid in WPF. The problem is everytime the program start, the datagrid automatically creates a new row at the bottom. This new row is not present in my ObservableCollection so editing it will be useless, as adding new item programmatically in my ObservableCollection will erase the data in the new row.
How can I disable the new row or make my ObservableCollection updated if user start editing in new row (just like in SQL Server management Studio)?
nb: If you can please give me an example of "correct" custom class in WPF, I'm still in WPF.
Meleak's answer from comment:
If you just want to disable that users can add new rows then set CanUserAddRows="False" in the DataGrid. The NewItemPlaceHolder that is the empty row, will be inserted into the ObservableCollection upon commit.

How to programmatically access a datagrid row details control

I've got a datagrid with some defined columns and then a row details template. How do I access a control in the row details template within the code behind? I've got a button that I want to programmatically enable/disable, but I can't figure out how to get access to it in the code behind. I've seen this on the MSDN:
http://msdn.microsoft.com/en-us/library/bb613579.aspx
but that's just describing a regular data template, so when I tried that it didn't work. My case is a row details data template. Surely someone has written code to access a control within a datagrid row details template that can comment on this (Would be much appreciated).
Okay, I figured out how to get this working I had to tweak the code that is posted in that MSDN article in the original question ....
DataGridRow row = (DataGridRow)(KeywordsGrid.ItemContainerGenerator.ContainerFromItem(KeywordsGrid.SelectedItem));
// Getting the ContentPresenter of the row details
DataGridDetailsPresenter presenter = FindVisualChild<DataGridDetailsPresenter>(row);
// Finding Remove button from the DataTemplate that is set on that ContentPresenter
DataTemplate template = presenter.ContentTemplate;
Button button = (Button)template.FindName("RemoveItemButton", presenter);
KeywordsGrid is the variable tied to my DataGrid. Notice in my call to FindVisualChild, I'm using a DataGridDetailsPresenter class instead of a ContentPresenter (this was the key... it forced the FindVisualChild method to iterate all the way through all the content presenters until I got to the one for the row details).
Use the DataGrid.LoadingRowDetails event! It is much more straight forward.
I found this here:
How to change Text of TextBlock which is in DataTemplate of Row Details for each DataGrid Row Details?
Example:
xaml
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<TextBlock x:Name="Test">Test</TextBlock>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
c#
private void dgVehicles_LoadingRowDetails(object sender, DataGridRowDetailsEventArgs e)
{
TextBlock tbTest = e.DetailsElement.FindName("Test") as TextBlock;
if (tbTest != null)
{
tbTest.Text = "Juhuu";
}
}
Can you define (or does there already exist) a property on the type of object being displayed in the grid that represents the enabled state of the button? If yes, then it would be much simpler to modify the row detail template to bind the button's IsEnabled property to that property.

Resources