I have a view model with a list of Invoices, these invoices are being displayed via a Telerik RadGridView This RadGridView has a RowDetailsTemplate. When I click on a row and expand to show the row details how can I pass the InvoiceViewModel of the selected RadGridViewRow so I can get those details from the database?
The purpose of not loading all of the information at once and waiting to load the details until after the row is selected is to reduce load time.
Here's some code for reference:
<telerik:RadGridView x:Name="InvoicesGridView"
ItemsSource="{Binding InvoicesForView}" DataContext="{Binding }"
RowDetailsVisibilityMode="VisibleWhenSelected"
// other stuff
telerik:GridViewVirtualizingPanel.IsVirtualizing="False" EnableRowVirtualization="False"
CanUserResizeColumns="False">
<i:Interaction.Triggers>
<i:EventTrigger EventName="RowDetailsVisibilityChanged" SourceObject="{Binding RelativeSource={RelativeSource AncestorType={x:Type telerik:GridViewRow}}}">
<i:InvokeCommandAction Command="{Binding DataContext.LoadInvoice, Source={StaticResource ViewContext}}" />
</i:EventTrigger>
</i:Interaction.Triggers>
<telerik:RadGridView.Columns>
<-- Column definitions -->
</telerik:RadGridView.Columns>
<telerik:RadGridView.RowDetailsTemplate>
<-- Row details stuff -->
</telerik:RadGridView.RowDetailsTemplate>
</telerik:RadGridView>
I've tried passing through a selected InvoiceViewModel and all that I get back is null, What can I set the CommandParameter to too get the information I need?
<telerik:RadGridView x:Name="InvoicesGridView"
ItemsSource="{Binding InvoicesForView}" DataContext="{Binding }"
ShowGroupPanel="False" Style="{StaticResource TransparentScrollBarStyle}"
RowIndicatorVisibility="Collapsed"
TextElement.Foreground="White"
TextElement.FontSize="12"
FontWeight="Normal" RowDetailsVisibilityMode="VisibleWhenSelected"
AutoGenerateColumns="False" SelectionMode="Multiple"
ShowColumnHeaders="True" RowHeight="24"
CanUserSelect="True" GroupRenderMode="Flat"
ScrollViewer.VerticalScrollBarVisibility="Visible"
ScrollViewer.CanContentScroll="True" ColumnWidth="*"
VirtualizingStackPanel.VirtualizationMode="Standard"
telerik:GridViewVirtualizingPanel.IsVirtualizing="False" EnableRowVirtualization="False"
CanUserResizeColumns="False">
<telerik:RadGridView.Columns>
<telerik:GridViewToggleRowDetailsColumn />
<-- Other columns -->
</telerik:RadGridView.Columns>
<telerik:RadGridView.RowDetailsTemplate>
<DataTemplate>
<Grid Background="#f8f8f8" TextElement.Foreground="Black" TextElement.FontWeight="Normal" TextElement.FontStyle="Normal" Margin="-1,0" MinHeight="20">
<telerik:RadTabControl >
<telerik:RadTabItem DataContext="{Binding}"/>
<i:Interaction.Behaviors>
<behaviors:RadTabControlTabChangeCommandBehavior>
<behaviors:RadTabControlTabChangeCommandBehavior.TabChangeCommands>
<behaviors:TabChangeCommand TabIndex="0" Command="{Binding Path=DataContext.LoadInvoice, Source={StaticResource ViewContext}}"/>
</behaviors:RadTabControlTabChangeCommandBehavior.TabChangeCommands>
</behaviors:RadTabControlTabChangeCommandBehavior>
</i:Interaction.Behaviors>
</telerik:RadTabControl>
<-- Other stuff -->
</telerik:RadGridView.RowDetailsTemplate>
</telerik:RadGridView>
The above is a nice little work around that worked for me
Related
I have datagrid to show some data in xaml of UWP application.I use MVVM and a i have view model for the view. Items source of datagrid is observable collection. I have problem with refresh data on xaml view. If i us DataGridTextColumn as column data, data refreshed properly on view, but if i use DataGridTemplateColumn data on view not refresh.
This code work properly:
<mtc:DataGrid Name="ArticlesListView"
ItemsSource="{x:Bind ViewModel.Articles, Mode=OneWay}"
AutoGenerateColumns="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
SelectionMode="Single"
RowDetailsVisibilityMode="Collapsed"
IsReadOnly="True">
<mtc:DataGrid.Columns>
<mtc:DataGridTextColumn Header="Barcode" Binding="{Binding Barcode}"/>
<mtc:DataGridTextColumn Header="Name" Binding="{Binding Description}"/>
</mtc:DataGrid.Columns>
</mtc:DataGrid>
I clear and fill observable collection with new data and data on view is refresh properly.
This code not work properly:
<mtc:DataGrid Name="ArticlesListView"
ItemsSource="{x:Bind ViewModel.Articles, Mode=OneWay}"
AutoGenerateColumns="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto"
SelectionMode="Single"
RowDetailsVisibilityMode="Collapsed"
IsReadOnly="True">
<mtc:DataGrid.Columns>
<mtc:DataGridTemplateColumn Header="Barcode">
<mtc:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:DataGridCell Background="{Binding Active, Converter={StaticResource BoolToColorConverter}, ConverterParameter=true}"
Data="{Binding Barcode}"/>
</DataTemplate>
</mtc:DataGridTemplateColumn.CellTemplate>
</mtc:DataGridTemplateColumn>
<mtc:DataGridTemplateColumn Header="Name">
<mtc:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:DataGridCell Background="{Binding Active, Converter={StaticResource BoolToColorConverter}, ConverterParameter=true}"
Data="{Binding Description}"/>
</DataTemplate>
</mtc:DataGridTemplateColumn.CellTemplate>
</mtc:DataGridTemplateColumn>
</mtc:DataGrid.Columns>
</mtc:DataGrid>
I clear and fill observable collection with new data but on view stays old data.
Can anyone help me with this issue?
Thank you for help. I figured out the problem. The problem is that property change event does not reach the custom control that i made for DataTemplate and changes does not apply in it. I change this lines of code:
<mtc:DataGridTemplateColumn Header="Barcode" Tag="Barcode">
<mtc:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:DataGridCell Background="{Binding Active, Converter={StaticResource BoolToColorConverter}, ConverterParameter=true}"
Data="{Binding Barcode}"/>
</DataTemplate>
</mtc:DataGridTemplateColumn.CellTemplate>
</mtc:DataGridTemplateColumn>
to this:
<mtc:DataGridTemplateColumn Header="Barcode" Tag="Barcode">
<mtc:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Grid Background="{Binding Active, Converter={StaticResource BoolToColorConverter}, ConverterParameter=true}">
<TextBlock Text="{Binding Barcode, Converter={StaticResource ObjectToStringConverter}}"
Style="{StaticResource DataGridCellContentStyle}"/>
</Grid>
</DataTemplate>
</mtc:DataGridTemplateColumn.CellTemplate>
</mtc:DataGridTemplateColumn>
and everything works fine. Its just have to define DataTemplate in datagrid not use external user control for DataTemplate because changes does not reach user control and does not apply to the view.
I have a telerik rad grid view and assigned buttons to one of the columns using DataTemplate.
<telerik:RadGridView ItemsSource="{Binding AllJobsCollection}"
Grid.Row="2"
SelectedItem="{Binding SelectedJob}">
<!--Jobs List Columns-->
<telerik:RadGridView.Columns>
<!--Pin button Column-->
<telerik:GridViewColumn>
<telerik:GridViewColumn.CellTemplate>
<DataTemplate>
<telerik:RadButton
Command="{Binding Path=DataContext.PinCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type telerik:GridViewDataControl}} }"
CommandParameter="{Binding}">
</telerik:RadButton>
</DataTemplate>
</telerik:GridViewColumn.CellTemplate>
</telerik:GridViewColumn>
<telerik:GridViewDataColumn Header="Job"
Width="Auto"
IsReadOnly="False"
DataMemberBinding="{Binding Name}"/>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
My question is how can I set the content of the button using DataMemberBinding.
I have a data table and i can pin some of the items and i change their Pinned property in database. I want to get the pinned property and set the buttons content accordingly.
You can't use DataMemberBinding within a CellTemplate. But you can bind the Content property to the any property of the current item, e.g.:
<telerik:RadButton
Command="{Binding Path=DataContext.PinCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type telerik:GridViewDataControl}} }"
CommandParameter="{Binding}"
Content="{Binding IsPinned}">
I have a WPF datagrid that is bound to a Realm backed object. The grid has an autocomplete box that allows the user to enter/select an account number which should then update the source object and the UI. Instead, when a selection is made, the UI box goes back to empty and the stored object is not updated. The Realm documentation states Modifying the collection (e.g. adding or removing items) must happen in a write transaction, so somehow, when the user makes a selection I need to trigger a write transaction on that specific row object. This is further confirmed by the error in the output window
System.Windows.Data Error: 8 : Cannot save value from target back to source. BindingExpression:Path=SAccount; DataItem='TransactionDetails' (HashCode=24381833); target element is 'DataGridRow' (Name=''); target property is 'NoTarget' (type 'Object') RealmInvalidTransactionException:'Realms.Exceptions.RealmInvalidTransactionException: Cannot modify managed objects outside of a write transaction.
I am trying to use an EventTrigger bound to a command in my VM but the trigger never fires. Can someone explain (or maybe even quickly demonstrate) how to make this work?
In my ViewModel I'm retreiving the object like this:
Transaction = realm.All<Transaction>().Where( t => t.ID == tid ).First();
and then binding it in my XAML view
<DataGrid x:Name="TransactionDataGrid"
DataGridCell.Selected="TransactionDataGrid_GotFocus"
AutoGenerateColumns="False"
CanUserSortColumns="True"
CanUserReorderColumns="False"
HorizontalAlignment="Left"
Margin="10,0,0,0"
VerticalAlignment="Top"
Height="556"
Width="1012"
CanUserAddRows="False"
ItemsSource="{Binding Transaction.Rows}"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<DataGrid.Columns>
<DataGridTextColumn x:Name="Source" Header="Source Account" Width="Auto" Binding="{Binding Description}" IsReadOnly="True" />
<DataGridTemplateColumn x:Name="AccountNum" Header="Account Number" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBox BorderThickness="0" Text="{Binding SAccount.RawAccountNumber}"/>
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<StackPanel>
<toolkit:AutoCompleteBox
Background="AliceBlue"
IsTextCompletionEnabled="True"
FilterMode="Contains"
MinimumPrefixLength="2"
ValueMemberPath="RawAccountNumber"
PreviewTextInput="AutoCompleteBox_PreviewTextInput"
SelectedItem="{Binding SAccount, Mode=TwoWay}"
Text="{Binding Path=SAccount.RawAccountNumber}"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Accounts}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction Command="{Binding UpdateRowCommand}"
CommandParameter="{Binding Path=ID}"/><!-- the command parameter should be the ID of the row we are updating? -->
</i:EventTrigger>
</i:Interaction.Triggers>
<toolkit:AutoCompleteBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" >
<TextBlock Text="{Binding Path=RawAccountNumber}" FontWeight="Bold" Width="100"/>
<TextBlock Text="{Binding Path=Description}" />
</StackPanel>
</DataTemplate>
</toolkit:AutoCompleteBox.ItemTemplate>
</toolkit:AutoCompleteBox>
</StackPanel>
The command in my ViewModel
public ICommand UpdateRowCommand
{
set
{
MessageBox.Show( "Hello UpdateRowCommand" );
}
}
Here is my code in XAML
<ListView x:Name="OpportunitySearchResultLV" ItemsSource="{Binding OpportunityCollection}" SelectionMode="Single" AlternationCount="2" ItemContainerStyle="{StaticResource alternatingListViewItemStyle}" SelectedItem="{Binding Path=SelectedOpportunitySearchedItem}" Margin="1" Grid.Row="3" Grid.Column="0" >
<ListView.InputBindings>
<MouseBinding Command="{Binding SelectOpportunitySearchDetailsCommand}" MouseAction="LeftClick"></MouseBinding>
<KeyBinding Command="{Binding SelectOpportunitySearchDetailsCommand}" Key="Up"></KeyBinding>
<KeyBinding Command="{Binding SelectOpportunitySearchDetailsCommand}" Key="Down"></KeyBinding>
<KeyBinding Command="{Binding OpportunitySearchDetailsLeaveCommand}" Key="Tab"></KeyBinding>
</ListView.InputBindings>
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource NOGridViewHeader}" >
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Viewbox>
<TextBlock Text="{Binding OpportunityTitle}"></TextBlock>
</Viewbox>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
<msia:Interaction.Triggers>
<msia:EventTrigger EventName="MouseMove">
<msia:InvokeCommandAction Command="{Binding SelectOpportunitySearchDetailsCommand}" />
</msia:EventTrigger>
</msia:Interaction.Triggers>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
now as you can see I am binding (MouseBinding and KeyBinding) but as I am using upkey and downkey I am unable to traverse through the rows in listview.It is stuck to only one row only. Can anyone advise me why this is happening ? My binding is working perfectly and as per expected result also.Moreover I would like to add that I have not found any way to bind GridViewColumn so I am binding (MouseBinding and KeyBinding) to Listview . Is it proper way or there is a better way to bind? Thanking you .Payel Mukherjee Bangalore India
I'm converting my project to use MVVM Light.
So far everything worked fine until I got stuck with binding ListViewItem MouseDoubleClick to a command.
Now it looks like that:
<ListView x:Name="ItemsFromStash" Grid.Column="0" Grid.Row="1"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding DropBox.DroppedItems}"
ItemTemplate="{DynamicResource DropItemTemplate}"
SelectedItem="{Binding DropBox.SelectedDropItem}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="Control.MouseDoubleClick"
Handler="EventSetter_OnHandler"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
I'd like to make it look somewhat like that:
<ListView x:Name="ItemsFromStash" Grid.Column="0" Grid.Row="1"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
ItemsSource="{Binding DropBox.DroppedItems}"
ItemTemplate="{DynamicResource DropItemTemplate}"
SelectedItem="{Binding DropBox.SelectedDropItem}">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<Custom:EventToCommand Command=
"{Binding DropBox.RenameItemCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
But it says:
Property 'Triggers' is not attachable to elements of type 'Style'
I tried moving the command to ListView.MouseDoubleClick, but than the SelectedItem is null sometimes.
How should do it?
The following code works for me on a listbox, it should be the same:
<ListBox x:Name="listbox_name_here"
ItemsSource="{Binding LastEntries}"
SelectedItem="{Binding SelectedExercise, UpdateSourceTrigger=PropertyChanged}"
MinHeight="150" ToolTip="Double click to edit"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Command:EventToCommand Command="{Binding your_command_name_here}"
CommandParameter="{Binding ElementName=listbox_name_here,
Path=SelectedItem}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ListBox>
Do note that the command parameter is using the listbox (listview in your case) name to bind the target for the selected item.
View:
<ListView x:Name="lw" ItemsSource="{Binding DroppedItems}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<Custom:EventToCommand Command="{Binding DataContext.RenameItemCommand, ElementName=lw}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.ItemTemplate >
<DataTemplate >
<Label Content="{Binding Field}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Your command:
private ICommand renameItemCommand;
public ICommand RenameItemCommand
{
get
{
if (renameItemCommand == null)
{
renameItemCommand = new RelayCommand(
param => RenameItem()
);
}
return renameItemCommand;
}
}
private void RenameItem()
{
}
One option could be to create a DataTemplate for the ListView items, and include your EventTrigger there. For example,
<ListView x:Name="ItemsFromStash"
ItemsSource="{Binding DropBox.DroppedItems}" ItemTemplate="{DynamicResource DropItemTemplate}"
SelectedItem="{Binding DropBox.SelectedDropItem}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<Custom:EventToCommand Command="{Binding DropBox.RenameItemCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<!-- Place your template controls here -->
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>