Search code examples
c#xamluwpxbox

Problem binding state for elements inside a ContentDialog


I'm currently trying to revive somebody else's project. In the original project there's a "MainMenu" page which utilizes a ContentDialog.

I've added a single checkbox to that menu and tried binding to it via x:Bind.

The MenuViewModel looks like this

namespace NScumm.MonoGame.ViewModels
{
    public class MenuViewModel : ViewModel, IMenuViewModel
    {
        private bool _showFPS;

        public bool ShowFPS
        {
            get { return _showFPS; }
            set 
            { 
                RaiseAndSetIfChanged(ref _showFPS, value);
            }
        }
    }
}

There's a more generic viewmodel that implements OnPropertyChanged

using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace NScumm.MonoGame.ViewModels
{
    public abstract class ViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var eh = PropertyChanged;
            eh?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public virtual void RaiseAndSetIfChanged<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
        {
            if (!EqualityComparer<T>.Default.Equals(field, value))
            {
                field = value;
                OnPropertyChanged(propertyName);
            }
        }
    }
}

Inside the codebehind I initialize the MenuViewModel

public MainMenuPage()
    {
        InitializeComponent();

        Vm = new MenuViewModel();
        DataContext = Vm;
    }

    public MenuViewModel Vm { get; set; }

Finally, in the XAML I add the checkbox

<CheckBox x:Name="ShowFPScheckBox" Margin="5" IsChecked="{x:Bind Vm.ShowFPS, Mode=TwoWay}">FPS Counter</CheckBox>

Whenever I close and re-open the menu, the checkbox is back to its default value of false.

Am I doing something wrong or is there a known issue with ContentDialog not retaining its state?


Solution

  • Whenever I close and re-open the menu, the checkbox is back to its default value of false.

     Vm = new MenuViewModel();
     DataContext = Vm;
    

    Every time you open the ContentDialog, a new Vm is created with the default Boolean value false.

    If you want ContentDialog to remember your choice, it is recommended that you use a database or local resource to save the user's selection and read it each time you open it.

    private void ContentDialog_Closing(ContentDialog sender, ContentDialogClosingEventArgs args)
    {
        bool isChecked = ShowFPScheckBox.IsChecked ?? false;
        ApplicationData.Current.LocalSettings.Values["FpsCheckBoxState"] = isChecked;
      
    }
    
    private void ContentDialog_Loaded(object sender, RoutedEventArgs e)
    {
        if (ApplicationData.Current.LocalSettings.Values["FpsCheckBoxState"]!=null)
        {
            ShowFPScheckBox.IsChecked = (bool)ApplicationData.Current.LocalSettings.Values["FpsCheckBoxState"];
        }
        else
        {
            ShowFPScheckBox.IsChecked = false;
        }
    
    }