In WPF xaml, I would like to make a custom data grid with button in cell. I want to create button in the last column as shown in below figure.
Custom data grid : Requirement
Here while pressing Add button some operation will happen and data will be added to that cell and button should be shown in next column.
I could add column with button using below code. But I don't know how add this button in the last column of of each row.
<DataGridTemplateColumn >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Height="30" Width="30"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
Related
I have got a WPF Application, which contains a Window, inside it there is a DataGrid. On Startup, the DataGrid is completely empty, its Columns are created at runtime by code.
I'm binding to a DataTable. The first coloumn is a single Text Field. I need to show one more Cell per Row, but as a Stackpanel, which itself holds some UserControls.
Actually I'm trying to first insert a blank column as placeholder for my StackPanel and later insert a StackPanel from Code to each Cell.
Unfortunately i don't get it running for some reasons. I cannot put a new Item to the Cell. Can anybody help me, please?
Best Regards,
Jonas
I would recommend to design and fill the datagrid via XAML.
YourItems is the Collection of object which you want to show
userControlColumn is the additional column for your usercontrol
firstColumn is your first DataGridTextColumn
<DataGrid x:Name="myGrid" ItemsSource="{Binding YourItems}">
<DataGrid.Columns>
<DataGridTemplateColumn x:Name="userControlColumn" Header="Column1">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ns:YourCustomControl/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn x:Name="firstColumn" Header="Columns2" Binding="{Binding YourDesiredProperty}"/>
</DataGrid.Columns>
</DataGrid>
Try and use a DataGridTemplateColumn, then you can put a stackpanel in each cell
I'm using the MVVM pattern with Xceed's WPF DataGridControl and I've bound a column of my grid to a boolean property on my view-model/data-context.
By default it displays as a checkbox, instead I'd like to display an image e.g. a smile face for True and a sad face for False. It doesn't need to behave like a checkbox as the column is read-only.
What is the best way to achieve this?
There was a blog posted on Xceeds website about how to style a DataCell based on other values. So essentially, you can create a DataTemplate with an image control in it and you can create a condition where you set the happy face if the value is true and a sad face if the value is false. Here is the following link that shows how to do this:
http://xceed.com/CS/blogs/techside/archive/2011/07/06/datacell-styling-vs-cellcontenttemplate.aspx
you have to create data grid template column to achieve custom style.
<DataGrid.Columns>
<DataGridTemplateColumn Header="First Name" IsReadOnly="True" Width="Auto" MinWidth="100" CanUserSort="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid>
<Image Source="smile.jpg"/>
<Image Source="smile.jpg"/>
</Grid>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
you can further use datatriggers to play with visibility of images
How can I display a button in a DataGridTemplateColumn only when its row is selected? I've tried this, but of course there is no IsSelected available to me. It doesn't make sense to have an IsSelected property on the entity to which the rows are bound, and even so I wouldn't want to have to couple my DataGrid to my model that tightly. Is there anyway that the interface can handle this itself?
This is what I have:
<sdk:DataGrid Name="_categorySummaryDataGrid"
MinHeight="200"
ItemsSource="{Binding ElementName=_userControl, Path=CategorySummaries}"
AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected">
<sdk:DataGrid.Columns>
<sdk:DataGridTextColumn x:Name="_nameColumn" Binding="{Binding Path=Name}" Header="Name" Width="Auto" IsReadOnly="True" />
<sdk:DataGridTextColumn x:Name="_descriptionColumn" Binding="{Binding Path=Description}" Header="Description" Width="*" IsReadOnly="True" />
<sdk:DataGridTemplateColumn x:Name="_detailsColumn" Width="Auto">
<sdk:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="..." ToolTipService.ToolTip="View Category Details"
Visibility="{Binding Path=IsSelected, Converter={StaticResource BooleanToVisibility}}"/>
</DataTemplate>
</sdk:DataGridTemplateColumn.CellTemplate>
</sdk:DataGridTemplateColumn>
</sdk:DataGrid.Columns>
</sdk:DataGrid>
For design reasons, I want the button to only show when the row that contains it is selected. And, if possible, I want it to show in a different way when the row is being hovered over.
There seem to be more limitations to Silverlight and WPF that I had hoped. I hope that these things are possible. Thanks. :)
Edit:
I do not have, and will not be getting Expression Blend. Thank you, that is all.
Whenever you want to change the visual appearance of anything in Silverlight, you have to think in terms of VisualStateManager. To change the appearance of a Selected DataGrid cell, you'll need to avail yourself to the wonders of VSM. By editing DataGridColumn.CellStyle's "Selected" state you can change the appearance of the selected grid cell.
In Blend, drag and drop a new DataGrid on a Page.
Right click on the DataGrid and choose "Add Column --> Add DataGridTemplateColumn"
Right click on the DataGridTemplateColumn in the "Object and timeline" pane and go "Edit Column Styles --> Edit CellStyle --> Edit Copy"
Right click on "Style" in the "objects and timeline" pane and go "Edit Template --> Edit Current".
Now comes the interesting part, how to specifically solve the problem of a disappearing button. If the button is the only thing you've got in that CellTemplate then you can just hide the whole contents of the cell.
Select the "Selected" state from the "States" pane.
Set the visibility of the ContentPresenter in the CellStyle.Template to Collapsed. (A nicer UX would be to add a 0.3seconds animation taking opacity from 100% to 0%).
Essentially this whole tutorial is about getting to the CellStyle.Template for your DataGridColumn and adding an animation to the Selected State.
I have been using WPF for quiet sometime. I know DataGrid in WPF does not have a Column collection as dependency property so columns cannot be added dynamically.
The application I am developing is highly dynamic so the number of columns are not known. So I am creating DataGridTemplate columns from code behind.
Problem 1 : I want alternating columns to have different background color. How do I do it programatically?? (DataGridTemplateColumn doesnot have a Background property so I am not able to figure out a solution)
Problem 2 : My DataGridTemplateColumn has a DataTemplate in which I have a StackPanel with 2 TextBoxes in it. There is an event in DataGrid called CellEditing Event which fires when we edit a cell. It works for default column, but for my column if I edit those TextBoxes, the event is snot getting fired!!! So how do I achieve it??
(I sometimes get amazed by WPF !!!)
Problem Zero You can have the columns in a datagrid generated for you if you use AutoGenerateColumns="true" when you set up your datagrid. It won't add columns dynamically later, but it might if you reset the itemssource? (not positive on that one)
Problem One DataGrid has properties AlternatingRowBackground and AlternationCount to set up alternating row backgrounds. But i don't see anything for alternating column backgrounds in the grid itself. You could do it inside your datatemplate, though:
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Background="Red" Foreground="White">I'm Red</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
But i still see a margin inside that even with margin=0, so the cells look funny if you use any really obvious colors.
Problem Two do you mean the CellEndEditing event? Because i don't see any other cell editing events. I tried the following:
<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False" CellEditEnding="DataGrid_CellEditEnding">
<DataGrid.Columns>
<DataGridTextColumn Header="A" Binding="{Binding Field0}" />
<DataGridTemplateColumn Header="BC">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Field1}"/>
<TextBlock Text="{Binding Field2}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Field1}"/>
<TextBox Text="{Binding Field2}" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
And my DataGrid_CellEditEnding event handler gets called whenever either of the textboxes in the CellEditingTemplate lose focus, whether data changed or not, so things appear to be working for me.
Are you using some other DataGrid than the "built in" WPF one?
I have a XAML based ContextMenu bound to the rows in a datagrid. It works just fine - until the grid is scrolled!
This is the context menu for one of the controls in the visual tree or a DataGrid row.
<data:DataGridTemplateColumn Header="Customer Details" Width="*">
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid Background="Transparent"> <!-- allows click in entire cell -->
<controlsInputToolkit:ContextMenuService.ContextMenu>
<controlsInputToolkit:ContextMenu>
<controlsInputToolkit:MenuItem Header="{Binding CompletedOrderId,StringFormat='Create Reminder for order #\{0\}'}"
CommandParameter="{Binding}">
<controlsInputToolkit:MenuItem.Command>
<command:CreateReminderCommand/>
</controlsInputToolkit:MenuItem.Command>
<controlsInputToolkit:MenuItem.Icon>
<Viewbox>
<Image Width="19" Height="18" Source="../images/reminders.png" VerticalAlignment="Center"/>
</Viewbox>
</controlsInputToolkit:MenuItem.Icon>
</controlsInputToolkit:MenuItem>
<controlsInputToolkit:ContextMenu>
<controlsInputToolkit:ContextMenuService.ContextMenu>
......
The ICommand is CreateReminderCommand and the CommandParameter is bound to the data item for the row itself.
This works just fine - I can right click on a row and it will show me the correct text in the menu item 'Create Reminder for order 12345'.
Then I scroll the datagrid down a page. If I keep right clicking on items then suddenly I'll see the wrong order number for a row. I think what must be happening is this :
The DataGrid is reusing instances of MenuItem that it has previously created.
How can I force a refresh of the ContextMenu when it is displayed for an item that changes? There's no 'Update method on the ContextMenu or ContextMenuService.
This turned out to be a Silverlight bug related to element binding.
http://blogs.msdn.com/delay/archive/2010/05/11/we-ve-secretly-changed-this-control-s-datacontext-let-s-see-if-it-notices-workaround-for-a-silverlight-data-binding-bug-affecting-various-scenarios-including-datagrid-contextmenu.aspx
The solution provided here fixes the problem.