WPF binding not updating the view
You need to implement INotifyPropertyChanged
in your ViewModel order to notify the View that the property has changed.
Here's a link to the MSDN page for it: System.ComponentModel.INotifyPropertyChanged
The most important thing to note is that you should raise the PropertyChanged
event in your property setter.
WPF Binding not updating XAML but PropertyChanged called
The reason why the binding to DisplayPopup
does not update is that the property is a computed property. A computed property lacks a setter and therefore never raises INotifyPropertyChanged.PropertyChanged
. The data binding listens to this event. As the result DisplayPopup.Get
is only called once (the moment the binding is initialized).
To solve this you can either let the MainViewModel
listen to PropertyChanged
events of the ContactViewModel
items or as it seems that you are interested in selected items simply bind the ListBox.SelectedItem
and change MainViewModel.DisplayPopup
on changes.
For simplicity I recommend the second solution.
Note that in order to make the ListBox.IsSelected
binding work you must set the ListBox.ItemContainerStyle
and target ListBoxItem
instead of ListBox
:
MainViewModel.cs
public class MainViewModel : BaseViewModel
{
public ObservableCollection<ContactViewModel> TankItems { get; set; }
private ContactViewModel selectedTankItem;
public ContactViewModel SelectedTankItem
{
get => this.selectedTankItem;
set
{
this.selectedTankItem = value;
OnPropertyChanged(nameof(this.SelectedTankItem));
this.DisplayPopup = this.SelectedTankItem != null;
}
// Raises INotifyPropertyChanged.PropertyChanged
public bool DisplayPopup { get; set; }
public MainViewModel() : base()
{
TankItems = new ObservableCollection<ContactViewModel>()
{
new ContactViewModel(),
new ContactViewModel()
};
}
}
MainWindow.xaml
<ListBox ItemsSource="{Binding TankItems}"
SelectedItem="{Binding SelectedTankItem}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="IsSelected"
Value="{Binding IsSelected, Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerStyle>
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type ContactViewModel}">
<StackPanel>
<TextBlock Text="Test" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<Border>
<TextBlock Text="{Binding DisplayPopup}" />
</Border>
wpf UI not updating?
You are setting a new value of property here:
AppliedJobsCollection = new ObservableCollection<AppliedJob>(appliedJobsList);
but it's a simple auto-property without notification.
Make it full property (view model needs to implement INotifyPropertyChange
):
ObservableCollection<AppliedJob> _appliedJobsCollection =
new ObservableCollection<AppliedJob>(); // empty initially
public ObservableCollection<AppliedJob> AppliedJobsCollection
{
get => _appliedJobsCollection;
set
{
_appliedJobsCollection = value;
RaisePropertyChanged(nameof(AppliedJobsCollection));
}
}
How does the full property behave? Is it as if all entries in each item in the collection have been changed (and thus have their properties changed)?
See this pseudo-code.
// given that AppliedJobsCollection is already initialized
// modify existing collection -> works
// bindings was subscribed to CollectionChanged event and will update
AppliedJobsCollection.Add(new AppliedJob(...));
// change item property -> works
// you implement INotifyPropertyChanged for items
// bindings was subscribed to that and will update
AppliedJobsCollection[0].Company = "bla";
// new instance of collection -> ... doesn't works
// how bindings can update?
AppliedJobsCollection = new ObservableCollection<AppliedJob>(...);
For last scenario to work you need to implement INotifyPropertyChanged
for a class containing AppliedJobsCollection
property and rise notification.
WPF DataBinding not updating?
In order to support data binding, your data object must implement INotifyPropertyChanged
Also, it's always a good idea to Separate Data from Presentation
public class ViewModel: INotifyPropertyChanged
{
private bool _test;
public bool Test
{ get { return _test; }
set
{
_test = value;
NotifyPropertyChanged("Test");
}
}
public PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
<Window x:Class="TheTestingProject_WPF_.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Viewbox>
<CheckBox IsChecked="{Binding Path=Test, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</Viewbox>
</Grid>
Code Behind:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel{Test = true};
}
}
WPF TreeView Binding not updating the View
The OnPropertyChanged("TestCases");
must be issued by the object that includes the property that changed. In your case, your class TestCaseNode
will need to call the OnPropertyChanged
method in order for the Treeview to recognize the change to the collection because that object holds the collection. That is, it is not simply some any property named "TestCases"
that has changed but the property in a specific object. The reason: you could have more than one properties with this name in different classes. And, if there are multiple copies of the object, they each have a property with the same name.
What I have done, and this has worked for me, is add a public method within the TestCaseNode
called UpdateProperties()
that then calls OnPropertyChanged("TestCases");
This ensures that the property update is issued by the correct object. Then I call this method when I need to have the control updated.
There are several other ways to do the same thing but I find this a simple and direct approach. You could, for example, include `OnPropertyChanged("TestCases"); in your add method. I have not done this because 1) the OnPropertyChanged call occurs too often and 2) without the OnPropertyChanged call I can defer the update to the control until after I've made several or all of my Add's.
WPF Binding is correct, but window does not update
Your properties need to raise the PropertyChanged event when they are changed. Your class should implement INotifyPropertyChanged
/// <inheritdoc cref="INotifyPropertyChanged"/>
public partial class YourViewModel : INotifyPropertyChanged
{
/// <inheritdoc/>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Notifies that a properties value has changed.
/// </summary>
/// <param name="propertyName">The property that has changed.</param>
public virtual void NotifyPropertyChanged([CallerMemberName]string propertyName = null)
{
this.CheckForPropertyErrors();
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
and then your properties should look like this:
private QuestionViewModel currentQuestion;
public QuestionViewModel CurrentQuestion
{
get
{
return this.currentQuestion;
}
set
{
this.currentQuestion = value;
this.NotifyPropertyChanged();
}
}
Related Topics
Questions About Entity Framework Context Lifetime
C#: How to Take a Screenshot of a Portion of Screen
"Padding Is Invalid and Cannot Be Removed" Using Aesmanaged
An Efficient Way to Base64 Encode a Byte Array
Comparing 2 Objects and Retrieve a List of Fields with Different Values
Using String as a Lock to Do Thread Synchronization
Size of a Class (Object) in .Net
Convert Datetime to a Specified Format
Missing Providername When Debugging Azurefunction as Well as Deploying Azure Function
Set Item Focus in Listview Wpf
Server.Mappath - Physical Path Given, Virtual Path Expected
C# Encryption to PHP Decryption
Update Requires a Valid Updatecommand When Passed Datarow Collection with Modified Rows
Remove Item in Dictionary Based on Value
Accessing a Property of Derived Class from the Base Class in C#
Why Does My .Net Application Crash When Run from a Network Drive