Reputation: 33
I am fairly new to XAML and WPF and have read numerous examples of how bind control properties but none seem to apply to my problem.
I have a static class Analyse that inherits INotifyPropertyChanged
Summary of the code below
class Analyse : INotifyPropertyChanged
{
public static DataSet moodleData; // Dataset containing the log data for analysis
private static bool dataPresent = true;
public static Boolean DataPresent
{
get { return dataPresent; }
set
{
if (dataPresent != value)
{
dataPresent = value;
NotifyStaticPropertyChanged("DataPresent");
}
}
}
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged
= delegate { };
private static void NotifyStaticPropertyChanged(string propertyName)
{
StaticPropertyChanged(null, new PropertyChangedEventArgs(propertyName));
}
#endregion
public static void clearData()
{
try
{
moodleData.Clear();
DataPresent = false;
}
catch { }
}
}
My XAML includes the name space local
<Window x:Name="TheMainWindow" x:Class="MoodleLogAnalyse.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"
xmlns:local="clr-namespace:MoodleLogAnalyse"
Title="MainWindow" Height="556.88" Width="793" WindowStartupLocation="CenterScreen">
And the button is bound correctly
<Button Name="OpenButton" Command="Open"
IsEnabled="{Binding Source={x:Static local:Analyse.DataPresent},
Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
Content="Open Grades" />
The property is definitely bound to the IsEnabled, changing the dataPresent definition manually in code enables and disables the button but a dynamic change such as switching between true and false such as calling the clear data method does not change the IsEnabled state of the button at run time.
The property change event is triggering as I have inserted break point to check.
I cannot see where I am going wrong with this! Any help would be appreciated.
Upvotes: 3
Views: 2251
Reputation: 2781
The Source
property is used to store the object which will be used as the alternative binding source (by default, bindings use DataContext
).
<Button IsEnabled="{Binding Source={x:Static local:Analyze.DataPresent}}" />
So when you use the code above then the Static
extension provides the current value of the DataPresent
property and that value is stored in the Source
property. In this case the binding uses a boxed constant value (true
or false
) as the source.
<Button IsEnabled="{Binding Path=(local:Analyze.DataPresent)}" />
But when you specify the Path
property, the binding locates your static class and binds to the property. In this case the static DataPresent
property is the source and the StaticPropertyChanged
event is used to notify the binding about updates.
The INotifyPropertyChanged
cannot be used in the case of binding to a static property because there is no instance is used to access that property. The corresponding static event must be used instead.
The name of the event must be equal to StaticPropertyChanged
and its type must be EventHandler<PropertyChangedEventArgs>
. Or the name must consist of two parts: the property name and suffix Changed
. In the last case the event's type must be EventHandler
because the event notifies only about changes of the corresponding property.
This means that:
Analyze
can be static because INotifyPropertyChanged
isn't necessary.StaticPropertyChanged
can be renamed to DataPresentChanged
and its type can be changed to EventHandler
.In other words:
public static class Analyze
{
public static DataSet moodleData; // Dataset containing the log data for analysis
private static bool dataPresent = true;
public static Boolean DataPresent
{
get { return dataPresent; }
set
{
if (dataPresent != value)
{
dataPresent = value;
DataPresentChanged(null, EventArgs.Empty);
}
}
}
public static event EventHandler DataPresentChanged = delegate { };
}
Useful links:
Upvotes: 4