Search code examples
wpfbindingpostsharp

WPF bindings not correct when window opens


I am writing a small WPF utility with a single window that so far has the code below. I'm using PostSharp to automatically handle the property change notifications and the bindings are updating as I select different organisations in the combobox. However when the window first opens and the line

organisationComboBox.SelectedIndex = 0;

executes, the bindings do not update. A breakpoint set in the organisationComboBox_SelectionChanged() method reveals that the _lightningLocationsEnabled variable is being set to true for the item selected, and that the properties depending on it are set correctly, yet the controls that the properties are bound initially display values they would if the variable was false.

The PostSharp documentation suggests that no manual forcing of property change notifications should be required so I presume I am doing something wrong. Can anyone help me find the problem?

Here is the code

using DynaMiX.Common.Groups.Constants;
using DynaMiX.Data.Operations;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using PostSharp.Patterns.Model;

namespace LightningMapLocationToolGUI
{
    [NotifyPropertyChanged]
    public partial class MainWindow : Window
    {
        private IOrganisationRepository _organisationRepository = new OrganisationRepository();
        private bool _lightningLocationsEnabled;

        public MainWindow()
        {
            InitializeComponent();
            BindOrganisations();
        }

        public string StatusText => $"Lightning Map Locations feature is { (_lightningLocationsEnabled ? "ENABLED" : "DISABLED") }";
        public Brush StatusColorBrush => new SolidColorBrush(_lightningLocationsEnabled ? Colors.Green : Colors.Red);
        public string EnableButtonText => _lightningLocationsEnabled ? "Disable" : "Enable";

        private void BindOrganisations()
        {
            var orgList = _organisationRepository
                .GetOrganisationSummaries()
                .Where(o => o.DatabaseState == DatabaseState.Active)
                .OrderBy(o => o.Name)
                .ToList();

            organisationComboBox.ItemsSource = orgList;
            organisationComboBox.DisplayMemberPath = "Name";
            organisationComboBox.SelectedValuePath = "OrganisationId";
            organisationComboBox.SelectedIndex = 0;
        }

        private void organisationComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            _lightningLocationsEnabled = _organisationRepository.LightningLocationsEnabledFor((long)organisationComboBox.SelectedValue);
        }
    }
}

and here is the XAML of the bound controls

<Label x:Name="statusLabel" Content="{Binding StatusText}" TextBlock.Foreground="{Binding StatusColorBrush}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="25,71,0,0"/>
<Button x:Name="enableButton" Content="{Binding EnableButtonText}" Visibility="{Binding ControlVisibility}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="309,74,0,0"/>

Solution

  • Put BindOrganisations in the Loaded event of the Window.

    Don't forget that the Loaded event can be called multiple time, you can use a boolean flag.