question

SudarshanGujar-4796 avatar image
0 Votes"
SudarshanGujar-4796 asked ·

WPF MVVM - Unable to bind Model property directly to the IsEnabled Property of Button

Hello Team,

Please find below View, ViewModel and Model class. I have binded collection of models (in ViewModel) to DataGrid control in the view. But based on UI selection, need to update another property in model. I am not able do to it via binding.

Actual Problem -

When combobox value gets changed on UI, we need to Enable the button. Somehow, I am not able to do it via databinding. Am I missing something ? Please help me.

View-

<UserControl x:Class="Poject.RelationshipControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation";
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml";
xmlns:d="http://schemas.microsoft.com/expression/blend/2008";
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">;

 <Grid x:Name="LayoutRoot">

     <Grid.RowDefinitions>
         <RowDefinition Height="Auto"/>
         <RowDefinition Height="75"/>
     </Grid.RowDefinitions>

     <StackPanel Orientation="Vertical">
        <StackPanel Orientation="Horizontal" Margin="5,10,0,0">
             <DataGridControl x:Name="DataGridData" 
                           BorderThickness="0" 
                           SelectionMode="Single"
                           GridLinesVisibility="None"
                           AutoGenerateColumns="False" 
                           MinHeight="380"
                           Width="Auto"
                           VerticalScrollBarVisibility="Auto"
                           ItemsSource="{Binding SignificantPersonData}"
                     <DataGridControl.Columns>
                     <sdk:DataGridTemplateColumn Header="Relationship" MinWidth="150">
                         <sdk:DataGridTemplateColumn.CellTemplate>
                             <DataTemplate>
                                 <ComboBox ItemsSource="{Binding RelationshipsToSignificantPerson, Mode=TwoWay}" 
                                       SelectedItem="{Binding SelectedRelationship, Mode=TwoWay}"
                                       Width="180" Margin="0,10,0,0"
                                       Height="30"/>
                             </DataTemplate>
                         </sdk:DataGridTemplateColumn.CellTemplate>
                     </sdk:DataGridTemplateColumn>

</DataGridControl.Columns>
</DataGridControl>
</StackPanel>
</StackPanel>

     <StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
         <Button Content="cancel" Height="55" IconHeight="35"
                                   IconWidth="35" Margin="10,0,20,0" Command="{Binding CancelCommand}"
                                   Style="{StaticResource CancelButton}"/>
         <Button Content="save" Height="55"
                                   IconHeight="35" IconWidth="35"
                                   IsEnabled="{Binding ElementName=DataGridData, Path=DataContext.IsEditable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                   Margin="20,0,10,0" Command="{Binding SaveCommand}"
                                   Style="{StaticResource SaveButton}"/>
     </StackPanel>
 </Grid>

</UserControl>
ViewModel -

private ObservableCollection<PersonDataModel> _significantPersonData;
public ObservableCollection<PersonDataModel> SignificantPersonData
{
get
{
return _significantPersonData;
}
set
{
_significantPersonData = value;
NotifyPropertyChanged(() => SignificantPersonData);
}
}

private void OnLoad()
{
SignificantPersonData.Add(new PersonDataModel
{
RelationshipsToSignificantPerson = relationshipsLibraryValues.ToList(),
SelectedRelationship = relationshipsLibraryValues.FirstOrDefault(x => x.stl_value == _relationship),
IsEditable = false
});
}

Model -

public class PersonDataModel : INotifyPropertyChanged
{
private List<stl_libraryvalueModel> _relationshipsToSignificantPerson;
public List<stl_libraryvalueModel> RelationshipsToSignificantPerson
{
get { return _relationshipsToSignificantPerson; }
set
{
_relationshipsToSignificantPerson = value;
NotifyPropertyChanged(() => RelationshipsToSignificantPerson);
}
}

     private stl_libraryvalueModel _selectedrelationship;
     public stl_libraryvalueModel SelectedRelationship
     {
         get { return _selectedrelationship; }
         set
         {
             _selectedrelationship = value;
             IsEditable = true;
             NotifyPropertyChanged(() => SelectedRelationship);
             NotifyPropertyChanged(() => IsDetailsVisible);
         }
     }

        
     private bool _isEditable;
     public bool IsEditable
     {
         get
         {
             return _isEditable;
         }
         set
         {
             _isEditable = value;
             NotifyPropertyChanged(() => IsEditable);
         }
     }
 }

Thanks.

windows-wpf
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

1 Answer

PeterFleischer-3316 avatar image
0 Votes"
PeterFleischer-3316 answered ·

Hi, use TrulyObservableCollection to detect changes in data objects. ViewModel consuming PropertyChanged event can check data objects and enable/disable button:

   /// <summary>
   /// Implements the "ItemPropertyChanged" Event for a ObservableCollection
   /// </summary>
   /// <typeparam name="T"></typeparam>
   /// <seealso cref="System.Collections.ObjectModel.ObservableCollection{T}" />
   public sealed class TrulyObservableCollection<T> : ObservableCollection<T>
   where T : INotifyPropertyChanged
   {
     /// <summary>
     /// Initializes a new instance of the <see cref="TrulyObservableCollection{T}"/> class.
     /// </summary>
     public TrulyObservableCollection() => CollectionChanged += FullObservableCollectionCollectionChanged;
    
     /// <summary>
     /// Initializes a new instance of the <see cref="TrulyObservableCollection{T}"/> class.
     /// </summary>
     /// <param name="pItems">The p items.</param>
     public TrulyObservableCollection(IEnumerable<T> pItems) : this()
     {
       foreach (var item in pItems) this.Add(item);
     }
    
     /// <summary>
     /// Fulls the observable collection collection changed.
     /// </summary>
     /// <param name="sender">The sender.</param>
     /// <param name="e">The <see cref="NotifyCollectionChangedEventArgs"/> instance containing the event data.</param>
     private void FullObservableCollectionCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
     {
       if (e.NewItems != null) foreach (Object item in e.NewItems) ((INotifyPropertyChanged)item).PropertyChanged += ItemPropertyChanged;
       if (e.OldItems != null) foreach (Object item in e.OldItems) ((INotifyPropertyChanged)item).PropertyChanged -= ItemPropertyChanged;
     }
    
     /// <summary>
     /// Items the property changed.
     /// </summary>
     /// <param name="sender">The sender.</param>
     /// <param name="e">The <see cref="PropertyChangedEventArgs"/> instance containing the event data.</param>
     private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e) => OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, sender, sender, IndexOf((T)sender)));
   }
· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.