RadGridView Button Column Content Binding to DataMember - c#

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}">

Related

Realm Update from WPF EventTrigger

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" );
}
}

Binding cascading combobox itemsource in wpf datagrid using mvvm

How to bind a 2nd dropdown based on first dropdown selected value of first dropdown using mvvm
Here is the class strcture
List<Location> Locations; //Application global cached data
List<Room> Room; //Application global cached data
class Location {LocationId, Name ....}
class Room{RoomId, Name, LocationId...}
XAML
<DataGridTemplateColumn Header="Property Name">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Name="LocationsComboBox"
ItemsSource="{Binding Path=DataContext.Locations, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
DisplayMemberPath="Name" SelectedValuePath="Id"
SelectedValue="{Binding PropertyId, UpdateSourceTrigger=PropertyChanged}">
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<!--Room Number-->
<DataGridTemplateColumn Header="Room Number">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox Name="RoomComboBox"
ItemsSource="{Binding Path=DataContext.Rooms, RelativeSource= {RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
DisplayMemberPath="RoomName" SelectedValuePath="RoomId"
SelectedValue="{Binding NewRoomId, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<i:InvokeCommandAction
Command="{Binding DataContext.PropertyChangedCommand,
RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}"
CommandParameter="{Binding}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
Did you use INotifypropertychanged ? you should implement INotifyPropertyChanged and change your child list when parent was changed
Use ObservableCollection<Room> instead of List (this will cause the second combobox to update when the first combo box changes the location which in turn causes the room collection to change.
Use ObservableCollection<Location> also. Your locations might not ever change, but this is simply good MVVM form.
I prefer Master Slave/Details way of combo box.
U can find Here
But in your Case
The binding for Room ComboBox should be from Code Behind on the basis of selected LocationID.
the below binding
ItemsSource="{Binding Path=DataContext.Rooms..
should be something like this
ItemsSource="{Binding Path=DataContext.RoomsInSelectedLocation
and in ViewModel
IEnumerable<Room> RoomsInSelectedLocation
{
return Rooms.where(r => r.LocationId == SelectedLocationId);
}
evaluate this every time the Location Combo selected item changes.

Button enbale/disable (inside Datagrid view ) based on value from Database -WPF

In WPF window, Data grid view will load from database.
This is the design code for Data grid view.(It contains 2 columns - Name, Action)
<DataGrid x:Name="dgrid" HorizontalAlignment="Left" Margin="0,65,0,0" VerticalAlignment="Top" >
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}" Width="160"></DataGridTextColumn>
<DataGridTemplateColumn Header="Action" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Name="btnEdit" Content="Edit" />
<Button Name="btnDelete" Content="Delete" />
<Button Name="btnActivate" Content="Activate" />
<Button Name="btnDeactivate" Content="Deactivate" />
</StackPanel>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Name column bind the value from data base value, and following column contain 4 buttons!
what I need to do this, based on another column value of database (for example Activation Status) , the btnActivate, btnDeactivate should set their
is Enable property!
how can I accomplish this?
Thanks in Advance
You need to initiate binding to appropriate property from your button:
<Button Name="btnEdit"
Content="Edit"
IsEnabled="{Binding DataContext.ActivationStatus, Converter={StaticResource MyStatusToBooleanConverter}, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type DataGridRow}}}" />
You should (providing your value in the DB is a boolean), use bindings to set the states.
For example:
<Button Name="btnActivate" Content="Activate" IsEnabled="{Binding ClassPropertyType}" />
And then when you set your ItemSource with a list of your class, it will bind to the set boolean.

MVVM Light - Listbox of UserControls, how to know on which ItemIndex a button is clicked

I got a Listbox where each item is a Usercontrol MatchPanel.
That UserControl has a button.
I d like to remove an item when I click on the button of that item.
I used the SelectedItem which is bind to my ViewModel and works well. But sometimes I m able to click on a button of one item without moving the SelectedItem value (the Listbox item dont get focused even if I click on the button of that item...).
Hence I m looking for a way to receive in the command CloseSelectedMatchCommand a parameter which would tell me, for the button I have clicked, at which index of the Listbox it is.
Thanks
Here is my View
<UserControl
DataContext="{Binding ListTradingMatches, Source={StaticResource Locator}}" Height="503.175" Width="409">
<ListBox ItemsSource="{Binding Path=ListMatches}" SelectedItem="{Binding Path=SelectedMatch}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<local:MatchPanel />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Here is my MatchPanel UserControl
<UserControl x:Class="MatchPanel"
<Label Content="Pts"/>
<Button Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListBox}},
Path=DataContext.CloseSelectedMatchCommand}" CommandParameter="{Binding}">
</Button>
</Grid>
You can set the DataContext of your UserControl to the item in the DataTemplate:
<DataTemplate>
<StackPanel>
<local:MatchPanel DataContext="{Binding}" />
</StackPanel>
</DataTemplate>
Now the DataContext is set to the item from the collection, you can set the CommandParameter to the relevant property from that object...:
<Button Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListBox}}, Path=DataContext.CloseSelectedMatchCommand}"
CommandParameter="{Binding Id}" />
..., or just the whole object:
<Button Command="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type ListBox}}, Path=DataContext.CloseSelectedMatchCommand}"
CommandParameter="{Binding}" />

Make default checked one particular checkbox in combobox with checkbox in data template

I have combobox with checkbox in data template. Combobox ItemSource property is binded with collection in ViewModel. I want to make one particular checkbox checked for default. How can I do this?
<ComboBox Grid.Column="1"
ItemsSource="{Binding MyCollection, Mode=OneWay}"
Style="{StaticResource MyComboboxStyle}"
Margin="5"
MinWidth="120">
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=DataContext.MyCheckedCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
Content="{Binding}"
IsChecked="false"
VerticalAlignment="Center"
Margin="3"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
I would make a boolean property in your viewmodel then upon loading of collection, find the object in your collection that should be checked and set if to true.
public bool IsChecked { get; set; }
XAML:
<CheckBox Command="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=DataContext.MyCheckedCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource Self}}"
Content="{Binding}"
IsChecked="{Binding IsChecked}"
VerticalAlignment="Center"
Margin="3"/>
However this may require you to have this property apart of you object model

Categories

Resources