I have a Telerik GridView. My GridView has several columns in it. The first column is a checkbox, and when I check or uncheck it, it changes a property in my Model named IsSelected!
The part of my code looks like this one:
<telerik:RadGridView>
<telerik:RadGridView.Columns>
<telerik:GridViewColumn Header=""
IsFilterable="False"
IsSortable="False"
IsReadOnly="True"
HeaderCellStyle="{StaticResource GridViewDefaultCheckboxStyles}">
<telerik:GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelected, Mode=TwoWay}"
Style="{StaticResource GridCheckBoxStyle}">
</CheckBox>
</DataTemplate>
</telerik:GridViewColumn.CellTemplate>
</telerik:GridViewColumn>
<!--Other columns-->
</telerik:RadGridView.Columns>
</telerik:RadGridView>
Now I want to remove the checkbox, and when I click a row in my grid(anywhere in the row), I want the IsSelected property to change its value. How can I achieve that?
I mean when I click a row, the selected row should be bound somehow to my IsSelected property, without braking the MVVM pattern.
Consider adding a custom behavior to the GridView that listens to the selection changed event, and updates the IsSelected item. This should keep your design clean.
Related
I have a JibGrid DataGrid like so (JibGrid is an open-source relatively simple subclass of a standard DataGrid to implement stuff like filtering etc):
<dataGrid:JibGrid ItemsSource="{Binding AvailableRDs}"
FilteredItemsSource="{Binding AvailableRDs}"
SelectedItem="{Binding SelectedAvailRD}"
AutoGenerateColumns="False" >
<dataGrid:JibGrid.Columns>
<DataGridCheckBoxColumn Header="Add?" Binding="{Binding Add}" Visibility="{Binding GetAddVisibility}"/>
<DataGridTextColumn Header="Tag" Binding="{Binding Tag}" />
<DataGridTextColumn Header="Revision Tag" Binding="{Binding RevisionTag}" />
<DataGridTextColumn Header="Current System" Binding="{Binding SystemStr}" />
</dataGrid:JibGrid.Columns>
</dataGrid:JibGrid>
The intent is that there is a custom class for each row that provides properties for the content of each cell in that row - Tag, RevisionTag, etc. All of that works fine. What I can't get to work is that Visibility binding. I would like for the checkbox in each row to be invisible if the CanAdd property on the class representing that Row in the DataContext returns False. When I add the Visibility binding in XAML as above, it seems that what happens is that WPF attempts to apply this binding to the actual column instead of for each row, so the binding fails to connect. I can go in using WPF explorer and manually bind a row's checkbox visibility DependencyProperty to the CanAdd property of the Row's datacontext, and that works fine, but I can't figure out how to, in XAML or code, cause it to generate that binding for the checkbox in every row automatically. Anybody have any ideas on that?
I have searched around for questions like this, and it seems that, for some reason, everybody wants to change the visibility of the column itself based on something in the datacontext of the whole grid, and nobody else wants to change the visibility of things in individual rows based on that row's datacontext. I tried the solution here while I was trying to figure this out, and that's what that answer is trying to do.
You can use DataGridTemplateColumn and BooleanToVisibilityConverter to achieve the desired result
Add BooleanToVisibilityConverter to your resources
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>
Set Converter for the DataGridTemplateColumn binding
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding Add}"
Visibility="{Binding CanAdd, Converter={StaticResource BoolToVis}}" ></CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
I have a C# WPF Datagrid, with a checkbox column, hyperlink columns and text columns.
My DataGrid is bound to a DataTable. The columns are not auto generated, but I do create them in code dynamically, since the number of columns is not known in advance.
I would like to enable the text in the cells to be selected (for ctrl+c purpose) but yet disable editing. I don't want the text to be changed.
Anyone can help?
One possibility is probably be to use a DataGridTemplateColumn:
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox IsReadOnly="True" Text="{Binding YourProperty,Mode=OneWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
This works also with Checkboxes, add a CheckBox, Bind its IsChecked and use as the content a TextBox that is set to IsReadOnly.
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding YourBooleanValue}">
<TextBox IsReadOnly="True" Text="YourCopyableTextOrABindingToText"/>
</CheckBox>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
If you want to have the checkbox readonly, set its Enabled-property to false. However in this case, you have to declare the TextBox not as a child but as a sibling of the CheckBox (use a grid or a StackPanel) for this.
If you want to make data readonly for the whole DataGrid, use:
<DataGrid IsReadOnly="True">
THis is also possible for columns:
<DataGridTextColumn IsReadOnly="True">
If you want to define it per row, you have to use DataGridTemplateColumns and bind the IsReadOnly-proeprty of the edit-control.
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox IsReadOnly="{Binind YourReadOnlyProperty}" Text="{Binding YourProperty,Mode=OneWay}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
If your users usually copy an entire cell at once you can set the DataGrid's SelectionUnit to Cell
If they copy sections of a cell you're better off overwriting the CellTemplate to display a Label as HCL recommended
I'm fairly sure that if you set the DataGridTextBoxColumn's IsReadOnly property to true, you'll still be able to select and copy the contents.
I have a Silverlight DataGrid control inside which I have a textbox and a button control.
It is as under
<dg:DataGrid x:Name="myGrid" AutoGenerateColumns="False">
<dg:DataGrid.Columns>
<dg:DataGridTemplateColumn Header="Name" Width="100">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Name}" x:name="txtName"/>
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
<dg:DataGridTemplateColumn Header="Age" Width="100">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Age}" x:name="txtAge"/>
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
<dg:DataGridTemplateColumn Header="Action" Width="100">
<dg:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="btnCilck" Content="Click" Click="btnClick_Click />
</DataTemplate>
</dg:DataGridTemplateColumn.CellTemplate>
</dg:DataGridTemplateColumn>
</dg:DataGrid.Columns>
</dg:DataGrid>
What I want to do is that at runtime I want to fetch the textbox value (txtName) for the row selected.
I mean, say the grid has 10 rows(i.e. 10 textbox's in that particular column; say Column Name) and 10 Buttons in say Action column(let's name it like that).
Now when I click on the 5th rows Click button, I want to get the value from the textbox present in that row.
Thanks in advance.
In the click event handler you can examine the sender's (Button's) DataContext, which will be the item represented by that row and will have the properties Name, Age etc.; you can get the property which is bound to the textbox.
A better design, assuming you designed your app with MVVM, is to have an ICommand in the ViewModel and bind the Button's Command property to that ICommand. In that case you can bind something to the CommandParameter of the button and receive it in the ICommand handler - either the DataContext itself with {Binding} or the actual property you're interested in.
Edit: sorry about going on with the Command bindings, they're not readily available in SL3; there are ways around it though, google it if you're interested. The commanding pattern will much better encapsulate the actions across your application.
There are actually ways to get to the actual contents of the grid cells, but I wouldn't recommend it, as it will come with a lot of overhead and will be fragile in case any of the templates change; it's much better to work with the actual data and leave the controls to do their jobs through bindings.
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 problem with a edit templete of cell in a WPF datagrid (WPF Toolkit). The template is builded with a ComboBox and the ItemsSource of
ComboBox are loaded at runtime.
This is the mean code...
<ObjectDataProvider x:Key="dataValuesProvider" MethodName="GetValues" />
<toolkit:DataGrid
ItemsSource="{Binding Path=MyItems}">
<toolkit:DataGridTemplateColumn
Header="Property1">
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Property1, ValidatesOnDataErrors=true}"/>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
<toolkit:DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox
SelectedValue="{Binding Path=Property1, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}"
IsEditable="True"
IsSynchronizedWithCurrentItem="False"
ItemsSource="{Binding Source={StaticResource dataValuesProvider}, Mode=OneWay}"
/>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellEditingTemplate>
</toolkit:DataGridTemplateColumn></toolkit:DataGrid>
Now, I have this problem.
I have to update the dataValuesProvider with different value on each rows. Then I have insert a reset of dataValuesProvider (dataValuesProvider=null) on selectionchanged event of datagrid.
(The dataValuesProvider will load after a input on a specific cell of the selected row).
This is the problem: when I reset the dataValuesProvider (on selectionchanged of a new row) it's modified the SelectedValue of ComboBox and the Property1 of previous row is cleared.
I think that there is this behavior becouse the editing template of cell not update the binding associations until I edit the cell. It's right?
How can I do to avoid this problem?
I have not yet resolved
however I have defined a simple project that show the problem.
You can download it from this link: http://pollosky.it/wp-content/uploads/2009/12/ObjectProviderTest.zip
Try to selectvalue from the second cell of the first row and then go to the second row. The value of property of first row is cleared!
How can I do?