I am trying to do something in WPF. I have a datagrid that I am binding with some values. What I need is that whenever I call that page the second time, I need to insert a button to all the cells of all the columns in the datagrid(except for the cells in the first column which are bound to some value). How can I do that? Please help.
R – How to add button dynamically in datagrid in wpf
buttondatagridwpf
Related Solutions
Here's a workaround for Binding Columns in the DataGrid. Since the Columns property is ReadOnly, like everyone noticed, I made an Attached Property called BindableColumns which updates the Columns in the DataGrid everytime the collection changes through the CollectionChanged event.
If we have this Collection of DataGridColumn's
public ObservableCollection<DataGridColumn> ColumnCollection
{
get;
private set;
}
Then we can bind BindableColumns to the ColumnCollection like this
<DataGrid Name="dataGrid"
local:DataGridColumnsBehavior.BindableColumns="{Binding ColumnCollection}"
AutoGenerateColumns="False"
...>
The Attached Property BindableColumns
public class DataGridColumnsBehavior
{
public static readonly DependencyProperty BindableColumnsProperty =
DependencyProperty.RegisterAttached("BindableColumns",
typeof(ObservableCollection<DataGridColumn>),
typeof(DataGridColumnsBehavior),
new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
private static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
DataGrid dataGrid = source as DataGrid;
ObservableCollection<DataGridColumn> columns = e.NewValue as ObservableCollection<DataGridColumn>;
dataGrid.Columns.Clear();
if (columns == null)
{
return;
}
foreach (DataGridColumn column in columns)
{
dataGrid.Columns.Add(column);
}
columns.CollectionChanged += (sender, e2) =>
{
NotifyCollectionChangedEventArgs ne = e2 as NotifyCollectionChangedEventArgs;
if (ne.Action == NotifyCollectionChangedAction.Reset)
{
dataGrid.Columns.Clear();
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Add)
{
foreach (DataGridColumn column in ne.NewItems)
{
dataGrid.Columns.Add(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Move)
{
dataGrid.Columns.Move(ne.OldStartingIndex, ne.NewStartingIndex);
}
else if (ne.Action == NotifyCollectionChangedAction.Remove)
{
foreach (DataGridColumn column in ne.OldItems)
{
dataGrid.Columns.Remove(column);
}
}
else if (ne.Action == NotifyCollectionChangedAction.Replace)
{
dataGrid.Columns[ne.NewStartingIndex] = ne.NewItems[0] as DataGridColumn;
}
};
}
public static void SetBindableColumns(DependencyObject element, ObservableCollection<DataGridColumn> value)
{
element.SetValue(BindableColumnsProperty, value);
}
public static ObservableCollection<DataGridColumn> GetBindableColumns(DependencyObject element)
{
return (ObservableCollection<DataGridColumn>)element.GetValue(BindableColumnsProperty);
}
}
To programatically add a row:
DataGrid.Items.Add(new DataItem());
To programatically add a column:
DataGridTextColumn textColumn = new DataGridTextColumn();
textColumn.Header = "First Name";
textColumn.Binding = new Binding("FirstName");
dataGrid.Columns.Add(textColumn);
Check out this post on the WPF DataGrid discussion board for more information.
Best Answer
You could add collapsed (hidden buttons that don't take up space) buttons to the cells and make them visible when needed.
This behaviour also can be bind to some condition with an IValueConverter on the visibility-property.
UPDATE tx to the comment I know there is a build in converter, so here's the deal :
where myContition is a property you have to create in your class. The value of this property should be true when you want your button to show , or false when you want it to be hidden..