Reputation: 167
I have the following code;
public partial class MainWindow : Window, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
bool _myValue;
public bool myValue
{
get { return _myValue; }
set {
_myValue = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("myValue"));
}
}
public MainWindow() {
myValue = false;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
void timer_Tick(object sender, EventArgs e) {
myValue = !myValue;
lblTime.Content = myValue.ToString();
}
}
and the corresponding xaml:
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
</Window.Resources>
<DockPanel Margin="10">
<Button x:Name="HideMe"
Height="50" Width="50"
Cursor="Hand"
Visibility="{Binding Path=myValue, Converter={StaticResource BoolToVis}}"/>
<Label x:Name="lblTime" />
</DockPanel>
What i am trying to do; is update the visibility of the button with every timer_tick; The label is updated, yet the binding refuses to work
I am very sure there is an oversight, but after following numerous tutorials, there is none on how I can make this work.. most work with a checkbox on the WPF; but I need the boolean in the codebehind to send to control the visibility of the button, once it's updated..
Upvotes: 1
Views: 88
Reputation: 116
mm8 gave you the perfect answer to your question (setting the data context) - I just want to point out one small thing that should make your life muchhhh easier when building your properties.
We can create a function to trigger the property changed event, requiring you to only write "OnPropertyChanged()" to trigger the UI update. To do this, we're going to add the 'void' below, telling it to use a property called "Caller Member Name" by default, unless you manually provide a property name (I.E. OnPropertyChanged("SomeOtherValue");).
To do this, we first need to add a using statement to the top of your UserViewModel class:
using System.Runtime.CompilerServices;
Then, we will add the OnPropertyChanged code and include the 'caller member name' It should look like this:
private void OnPropertyChanged([CallerMemberName] String name = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
Now - we will update your property to use the simplified method:
public bool myValue
{
get { return _myValue; }
set
{
_myValue = value;
OnPropertyChanged();
}
}
Lastly - I've personally prefer a streamlined way for get/set's - What you're doing is completely OK and there is no need to change it if you don't want to, but i'd suggest trying it this way to see how you like it :)
public bool MyValue
{
get => _myValue;
set
{
// If the value hasn't changed, the code will return (Exit) - avoiding a false property changed trigger :)
if (_myValue == value) return;
_myValue = value;
OnPropertyChanged();
}
}
Reasons: Checking to see if the value has actually changed in your SET will prevent false triggers, you use less brackets, and intellisense makes writing this super easy!
Let me know if you have any questions!
Upvotes: 0
Reputation: 169200
Set the DataContext
of the window to itself and don't forgot to call InitializeComponent()
:
public MainWindow()
{
InitializeComponent();
DataContext = this; //<--
myValue = false;
DispatcherTimer timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromSeconds(1);
timer.Tick += timer_Tick;
timer.Start();
}
Upvotes: 1