WPF - Xceed GridControl - saving when edited row has focus - wpf

I have an XCeed grid with cell editing enabled.
When i make a change to my cell, leave the row and then save it is persited to the database.
But when i hit my save button when the changed cell is still selected the change doens't get persisted.
How can i make sure when i save the current content is saved?
My Grid xaml:
<xcdg:DataGridControl ItemsSource="{Binding Source={StaticResource MySource}}"
BorderThickness="1" AutoCreateColumns="False" ReadOnly="False" NavigationBehavior="CellOnly">
<xcdg:DataGridControl.DefaultCellEditors>
<xcdg:CellEditor x:Key="{x:Type system:Boolean}">
<xcdg:CellEditor.EditTemplate>
<DataTemplate>
<xcdg:CheckBox xcdg:Cell.IsCellFocusScope="True"
IsChecked="{xcdg:CellEditorBinding}"
HorizontalContentAlignment="Right"
/>
</DataTemplate>
</xcdg:CellEditor.EditTemplate>
<xcdg:CellEditor.ActivationGestures>
<xcdg:TextInputActivationGesture />
</xcdg:CellEditor.ActivationGestures>
</xcdg:CellEditor>
</xcdg:DataGridControl.DefaultCellEditors>
<xcdg:DataGridControl.Columns>
<xcdg:Column Title="Description" FieldName="Description" ReadOnly="True"/>
<xcdg:Column Title="Start period" FieldName="Start" ReadOnly="True"/>
<xcdg:Column Title="End Period" FieldName="End" ReadOnly="True"/>
<xcdg:Column Title="Finished" FieldName="IsFinished"/>
</xcdg:DataGridControl.Columns>
<!--<xcdg:DataGridControl.Columns>
</xcdg:DataGridControl.Columns>-->
</xcdg:DataGridControl>

Related

RadGridView Bind Column Width to Another Column?

I have a RadGridView (Telerik) and it has a handful of columns. In the row details template I have another grid view displaying sub-items that have the same columns. This works great for the initial display, but I would like the column widths for the details template to follow the widths of the main grid (details template does not have headers).
I tried giving the main column a name and binding to 'Width' and 'ActualWidth' properties of that column by name but it didn't seem to take and didn't give any binding errors.
Is there any way to bind the width of a column on one RadGridView to the width of a column on another RadGridView?
EDIT
Per the suggestion below I tried binding the view to the tag and going that way and it doesn't seem to work. It works for the textblock but doesn't set the column width. Here is a video of what I see:
https://www.screencast.com/t/BiHmiarQExV
Here is the code I'm using:
<telerik:RadGridView Grid.Row="2" ItemsSource="{Binding RenumberNotes}" x:Name="tgr" AutoGenerateColumns="False"
RowDetailsVisibilityMode="Visible">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn UniqueName="columnName" DataMemberBinding="{Binding CurrentValue}" Width="100" />
</telerik:RadGridView.Columns>
<telerik:RadGridView.RowStyle>
<Style TargetType="telerik:GridViewRow" BasedOn="{StaticResource {x:Type telerik:GridViewRow}}">
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=telerik:RadGridView}}" />
</Style>
</telerik:RadGridView.RowStyle>
<telerik:RadGridView.RowDetailsTemplate>
<DataTemplate>
<StackPanel>
<StackPanel Orientation="Horizontal" Margin="10,10,10,10">
<TextBlock Text="Column width: " />
<TextBlock
Text="{Binding Tag.Columns[columnName].ActualWidth, RelativeSource={RelativeSource AncestorType=telerik:GridViewRow}}" />
</StackPanel>
<telerik:RadGridView AutoGenerateColumns="False" ItemsSource="{Binding Subnotes}">
<telerik:RadGridView.Columns>
<telerik:GridViewColumn Header="test" Width="{Binding Tag.Columns[columnName].ActualWidth, RelativeSource={RelativeSource AncestorType=telerik:GridViewRow}}" />
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</StackPanel>
</DataTemplate>
</telerik:RadGridView.RowDetailsTemplate>
</telerik:RadGridView>
As you can see, it updates the textblock properly so the binding is correct, but the column width is not updated.
Is there any way to bind the width of a column on one RadGridView to the width of a column on another RadGridView?
Yes. You could define a RowStyle that binds the Tag property of the GridViewRow to the parent RadGridView and then use this one to bind to the Columns collection of the grid. Here is an example for you:
<telerik:RadGridView x:Name="tgr" AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn UniqueName="columnName" DataMemberBinding="{Binding Name}" Width="100" />
</telerik:RadGridView.Columns>
<telerik:RadGridView.RowStyle>
<Style TargetType="telerik:GridViewRow" BasedOn="{StaticResource {x:Type telerik:GridViewRow}}">
<Setter Property="Tag" Value="{Binding RelativeSource={RelativeSource AncestorType=telerik:RadGridView}}" />
</Style>
</telerik:RadGridView.RowStyle>
<telerik:RadGridView.RowDetailsTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Margin="10,10,10,10">
<TextBlock Text="Column width: " />
<TextBlock Text="{Binding Tag.Columns[columnName].ActualWidth, RelativeSource={RelativeSource AncestorType=telerik:GridViewRow}}" />
</StackPanel>
</DataTemplate>
</telerik:RadGridView.RowDetailsTemplate>
</telerik:RadGridView>
Edit:
It works for a Textblock as you have shown, but binding the column width the same way doesn't seem to do anything.
Right, that's because the column itself is not part of the visual tree. You will have to write some code then. You could simply handle the Loaded event of the inner RadGridView:
private void RadGridView_Loaded(object sender, RoutedEventArgs e)
{
RadGridView subGridView = (RadGridView)sender;
subGridView.Columns[0].Width = columnName.Width;
}
XAML:
<telerik:RadGridView Grid.Row="2" ItemsSource="{Binding RenumberNotes}" x:Name="tgr" AutoGenerateColumns="False"
RowDetailsVisibilityMode="Visible">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn x:Name="columnName" DataMemberBinding="{Binding CurrentValue}" Width="100" />
</telerik:RadGridView.Columns>
<telerik:RadGridView.RowDetailsTemplate>
<DataTemplate>
<telerik:RadGridView AutoGenerateColumns="False" ItemsSource="{Binding Subnotes}"
Loaded="RadGridView_Loaded">
<telerik:RadGridView.Columns>
<telerik:GridViewColumn Header="test" />
</telerik:RadGridView.Columns>
</telerik:RadGridView>
</DataTemplate>
</telerik:RadGridView.RowDetailsTemplate>
</telerik:RadGridView>
This is cleaner and doesn't break any pattern.

Xceed themes override all other styles

I'm using an xceed datagrid with the Office2007BlackTheme. I also have a lot of styles, that I want to apply to UI controls inside my datagrid. Unfortunately the theme seems to override everything as long as its inside the datagrid.
It is worth noting that datagrid-related styles like "ColumnManagerCell" or "DataRow" still work as expected.
For example: I want to use my own style for the scrollbars, but even though the style is set to be applied globally; <Style TargetType="{x:Type ScrollBar}">, it is still overridden in the datagrid. Outside of the grid it is not.
I realize that this is because, by default, the theme is set implicitly, but there doesn't seem to be anyway of setting it explicitly.
Is there a way to explicitly set the ScrollBar style (& others) after applying the theme? Maybe there's a way to base the tableflowview on the theme so it doesn't override other styles? I've looked around and did not find any solution.
I'm using Xceed DataGrid for WPF 6.3 with ThemePack 1-5. (Only DataGrid: xceed.com/xceed-datagrid-for-wpf paid version)
Any help is appreciated.
Here's my code for the DataGrid:
<xcdg:DataGridControl x:Name="datagrid"
ItemsSource="{Binding Source={StaticResource Features}}"
KeyUp="DatagridKeyUp"
AllowDetailToggle="True"
Margin="10"
NavigationBehavior="RowOrCell"
CellEditorDisplayConditions="RowIsBeingEdited,
MouseOverCell, MouseOverRow, RowIsCurrent, CellIsCurrent"
EditTriggers="BeginEditCommand, ClickOnCurrentCell,
SingleClick, CellIsCurrent, ActivationGesture, RowIsCurrent"
ItemScrollingBehavior="Immediate"
AutoCreateColumns="False">
<xcdg:DataGridControl.View>
<xcdg:TableflowView>
<!--Remove ugly header-->
<xcdg:TableflowView.FixedHeaders>
<DataTemplate>
<xcdg:ColumnManagerRow />
</DataTemplate>
</xcdg:TableflowView.FixedHeaders>
<!-- THEME IS SET HERE! -->
<xcdg:TableflowView.Theme>
<xcdg:Office2007BlackTheme/>
</xcdg:TableflowView.Theme>
</xcdg:TableflowView>
</xcdg:DataGridControl.View>
<xcdg:DataGridControl.Resources>
<Style TargetType="xcdg:TableViewScrollViewer">
<Setter Property="HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="VerticalScrollBarVisibility" Value="Auto" />
</Style>
</xcdg:DataGridControl.Resources>
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="FeatureID" Title="FeatureID" ReadOnly="True"/>
<xcdg:Column FieldName="Name" Title="Feature name" ReadOnly="True" />
<xcdg:Column FieldName="Description" Title="Description" ReadOnly="True" />
<xcdg:UnboundColumn FieldName=" " />
</xcdg:DataGridControl.Columns>
<xcdg:DataGridControl.DetailConfigurations>
<xcdg:DetailConfiguration RelationName="Settings" UseDefaultHeadersFooters="False">
<xcdg:DetailConfiguration.Headers>
<DataTemplate>
<xcdg:ColumnManagerRow />
</DataTemplate>
</xcdg:DetailConfiguration.Headers>
<xcdg:DetailConfiguration.Columns>
<xcdg:Column FieldName="Name" Title="Name" ReadOnly="True" />
<xcdg:Column FieldName="Description" Title="Description" ReadOnly="True" />
<xcdg:Column FieldName="EditValues" Title="Edit Values" ReadOnly="True" />
<xcdg:Column FieldName="EditValueVar" Title="Edit Value" Width="150" ReadOnly="False"
CellContentTemplateSelector="{StaticResource SettingsDataTemplateSelector}"
DisplayMemberBinding="{Binding}" />
<xcdg:UnboundColumn FieldName=" " />
</xcdg:DetailConfiguration.Columns>
</xcdg:DetailConfiguration>
</xcdg:DataGridControl.DetailConfigurations>
</xcdg:DataGridControl>

WPF Xceed Data grid Scroll view

I have use Xceed data grid with more than 20 columns when i use 20th column and do any action my grid scrollbar start with column no 1 how to avoid such refreshing issue ?
<xcdg:DataGridControl AllowDrop="True" AutoCreateColumns="False" ReadOnly="True" Name="xcddgVSMilestones" ItemScrollingBehavior="Immediate" MouseDoubleClick="xcddgVSMilestones_MouseDoubleClick" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="Column01" ReadOnly="True" Title="Column 01 ">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType={x:Type xcdg:DataRow}}, Path=DataContext[OriginalDate], StringFormat=\{0: MM/dd/yyyy\}}"/>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
</xcdg:Column>.......... up to column20
</xcdg:DataGridControl.Columns>
</xcdg:DataGridControl>
This Xaml code was i use

Single-click-editable bound CheckBox in Xceed DataGridControl

I've spent the past hour searching for solutions to what should be a simple problem: how to create a single-click-editable bound CheckBox in Xceed's community DataGridControl.
To be clear: I want a CheckBox column where the user may click any CheckBox, regardless of what row is selected, and have the view model's IsSelected property changing accordingly.
Below is the latest permutation I've tried. This code reads the value from the model, but clicking the CheckBox does not call the IsSelected setter for some reason.
<xcdg:DataGridControl x:Name="DictionariesDataGridControl" ItemsSource="{Binding Mode=OneWay, Source={StaticResource DictionariesViewSource}}" AutoCreateColumns="False" AutoRemoveColumnsAndDetailConfigurations="False" SelectionMode="Extended" NavigationBehavior="RowOnly">
<xcdg:DataGridControl.View>
<xcdg:TableView UseDefaultHeadersFooters="False" ShowRowSelectorPane="False" VerticalGridLineThickness="0">
<xcdg:TableView.FixedHeaders>
<DataTemplate>
<xcdg:ColumnManagerRow BorderThickness="0"/>
</DataTemplate>
</xcdg:TableView.FixedHeaders>
</xcdg:TableView>
</xcdg:DataGridControl.View>
<xcdg:DataGridControl.Columns>
<xcdg:Column FieldName="IsSelected" MinWidth="20" MaxWidth="20" CellEditorDisplayConditions="RowIsCurrent">
<xcdg:Column.CellContentTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding ., Mode=OneWay}" IsHitTestVisible="False"/>
</DataTemplate>
</xcdg:Column.CellContentTemplate>
<xcdg:Column.CellEditor>
<xcdg:CellEditor>
<xcdg:CellEditor.EditTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding ., Mode=TwoWay}"/>
</DataTemplate>
</xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>
</xcdg:Column.CellEditor>
</xcdg:Column>
</xcdg:DataGridControl.Columns>
EDIT 1
I'm trying this, which does exactly what I need:
<xcdg:Column FieldName="IsSelected" MinWidth="20" MaxWidth="20" CellEditorDisplayConditions="Always"/>
except that, for some reason, the CheckBox is styled with a blue background!
I've selected the element in the visual tree that has a Background property defined as SolidColorBrush with #FF0000FF as the color:
EDIT 2
I decompiled the DataGridCheckBox class that Xceed uses to render the CheckBox and found this override:
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.ChildCheckBox.Background = (Brush) new SolidColorBrush(Colors.Blue);
}
What a bizarre decision by Xceed to arbitrarily set the background color to blue.
EDIT 3
Using #JBrooks' answer, I tried the following:
<xcdg:Column FieldName="IsSelected" MinWidth="20" MaxWidth="20" CellEditorDisplayConditions="Always">
<xcdg:Column.CellEditor>
<xcdg:CellEditor>
<xcdg:CellEditor.EditTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding ., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</xcdg:CellEditor.EditTemplate>
</xcdg:CellEditor>
</xcdg:Column.CellEditor>
</xcdg:Column>
Unfortunately, for some reason the setter on the IsSelected property is never called when I check the box. The getter is called several times, though, and the CheckBoxes are appearing correctly on initial bind.
You have both a CellContentTemplate and a CellEditor, so the first click does the "go into edit mode" logic. Just have a single one like below. This is for a normal WPF DataGrid, but maybe you can try something similar for your grid.
<DataGridTemplateColumn Header="Active" SortMemberPath="IsActive" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsActive, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding IsEnabled}" Style="{StaticResource rightsCB}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
For this DataGrid I also have these properties set:
SelectedItem="{Binding SelectedUser, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectionUnit="FullRow" SelectionMode="Single"
So this DataGrid does act like what you want - I click the checkbox in row 4 and the IsChecked changes and it also makes row 4 the current row which sets the SelectedUser to the user bound to row 4.

Strange behavior with CheckBox in DataGridTemplateColumn

I have a SL4 DataGrid with a column containing a checkbox:
<data:DataGridTemplateColumn Header="Check" CanUserSort="False" >
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="CheckRead" Click="CheckRead_Click" IsChecked="{Binding Acknowledged, Mode=TwoWay}" />
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
Everything works fine as long as the user clicks directly on the checkbox. If they click anywhere else in the cell, the cell gets selected. But on subsequent clicks on the checkbox - the checkbox changes state but that change is not reflected in the bound object.
If the user clicks on any other cell and then goes back to click the checkbox, it works again.
Why does having the cell selected disable the binding of the checkbox????
I tried the solution proposed of setting horizontal/vertical alignment to stretch but that does not change anything.
Okay, the answer is...
<data:DataGridTemplateColumn Header="Check" CanUserSort="False" >
<data:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ContentControl HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalAlignment="Center">
<CheckBox x:Name="CheckRead" Click="CheckRead_Click" IsChecked="{Binding Acknowledged, Mode=TwoWay}" />
</ContentControl>
</DataTemplate>
</data:DataGridTemplateColumn.CellTemplate>
</data:DataGridTemplateColumn>
Wrapping the checkbox in a contentcontrol like this causes the problem to go away!

Resources