【问题标题】:Update 2 different classes from a settings flyout?从设置弹出窗口更新 2 个不同的类?
【发布时间】:2013-05-18 21:17:01
【问题描述】:

根据 MSDN 指南,我们需要将应用程序的所有设置放入 SettingsPane,然后应用程序应在应用设置时更新所有页面。

在我的应用程序中,我需要一个重置选项,将应用程序恢复为默认设置。按下重置按钮时,我需要更新 2 个页面,Calendar.xaml 和 HistoryStatistics.xaml。应用程序的所有数据都放在一个名为 CycleManager 的单例类中。我使用了 Callisto Toolkit 中的 SettingsFlyout 控件。

App.Xaml

在 App.xaml 中注册设置

SettingsPane.GetForCurrentView().CommandsRequested += OnCommandsRequested;

OnCommandsRequested 函数中,创建了重置处理程序

        var reset = new SettingsCommand("reset", "Reset", (handler) =>
        {
            var settings = new SettingsFlyout();
            settings.Content = new ResetUserControl();
            settings.HeaderBrush = new SolidColorBrush(_background);
            settings.Background = new SolidColorBrush(_background);
            settings.HeaderText = "Reset";
            settings.IsOpen = true;
        });

        args.Request.ApplicationCommands.Add(reset);

CycleManager.cs

在 CycleManager 类中,有一个 m_Reset 变量、它的 setter 和 getter 以及一个名为 ResetClicked 的事件处理程序

    public event EventHandler ResetClicked;

    public bool Reset
    {
        get
        {
            return m_reset;
        }
        set
        {
            m_reset = value;
            if (ResetClicked != null)
                ResetClicked(this, EventArgs.Empty);
        }
    }

接下来是我在第一类 calendar.xaml 中关联此处理程序的部分

Calendar.xaml

在类的构造函数中我声明了事件处理程序

CycleManager pCycMan = CycleManager.Instance;
pCycMan.ResetClicked += this.ResetClicked;

后跟事件处理程序的定义

    private async void ResetClicked(object sender, EventArgs e)
    {
        CycleManager pCycMan = CycleManager.Instance;
        if (pCycMan.Reset == true)
        {
            try
            {                   
                await Windows.Storage.ApplicationData.Current.ClearAsync(Windows.Storage.ApplicationDataLocality.Local);
                pCycMan.InitializeValues();
            }
            catch (Exception)
            {
            }
        }

        CreateCalendar();// UI is loaded
    }  

在 HistoryStatistics.xaml 的构造函数中,我做了和上面一样的事情

HistoryStatistics.xaml

public HistoryStatistics()
    {
        CycleManager pCycMan = CycleManager.Instance;
        pCycMan.ResetClicked += this.ResetClicked;
    }

并定义

    private void ResetClicked(object sender, EventArgs e)
    {
        CycleManager pCycMan = CycleManager.Instance;
        if (pCycMan.Reset == true)
        {
            await Windows.Storage.ApplicationData.Current.ClearAsync(Windows.Storage.ApplicationDataLocality.Local);
            pCycMan.InitializeValues();
            LoadListView();// loads the UI
            DisplayStatistics();//loads the UI for the page
        }
    } 

现在的问题

  1. 这是正确的方法吗?

  2. 当在第二页的第一页(HistoryStatistcs)中按下重置时,首先调用在第一页(Calendar.xaml.cs)中声明的重置单击函数,然后调用 HistoryStatistics 中的函数。两者都被异步执行! :( 这是正确的行为吗?

这个问题很长。希望大家理解场景和问题。

【问题讨论】:

    标签: c# windows-8 settings flyout


    【解决方案1】:

    由于未使用 MVVM(模型、视图和视图模型)分离,因此很可能会出现复杂性/混乱。您可能想了解这一点。保持分离有帮助。以下是这方面的一些提示。但不一定是您应用的完整设计。

    在这个例子中:CycleManager.Instance 是一种为模型(数据)服务。您可能希望将 ResetClicked 重命名为 SettingChanged,并将该事件视为通知客户端公开的一个或多个设置属性已更改。它还应该公开可由 ResetUserControl 调用的 ResetSettings() 方法。

    // model for the settings
    class SettingsManager
    {
        public event EventHandler SettingsChanged;
    
        public async void ResetSettings()
        {
            await Windows.Storage.ApplicationData.Current.ClearAsync
                  (Windows.Storage.ApplicationDataLocality.Local);
            // initialize all values to default values;
            this._intializeValues();
            if (this.SettingsChanged != null)
                this.SettingsChanged(this, EventArgs.Empty);
        }
    }
    

    HistoryStatistics 和 Calendar 类应该具有应该侦听 SettingsChanged 事件并更新公开的属性的视图模型。每个页面视图 (xaml) 都绑定到相应视图模型公开的属性。这将需要对当前代码进行一些重构。

    否则,ResetClick 事件处理程序可以更改为 SettingChanged 事件处理程序并采取所需的操作。他们不需要调用设置管理器来初始化值。

    class HistoryStatistics
    {
        private void SettingsChanged(object sender, EventArgs e)
        {
            SettingsManager settingsManager = SettingsManager.Instance;
            LoadListView();// loads the UI
            DisplayStatistics();//loads the UI for the page
        } 
    }
    

    HTH。

    【讨论】:

      【解决方案2】:

      你描述的行为没有错。两个页面订阅一个事件,并且事件使用多播委托,这意味着它们都会被解雇。

      我认为你需要一个更简单的行为。每个 xaml 页面都应在 OnNavigatedTo 上订阅该事件,并应在 OnNavigatedFrom 中取消订阅。

      这样只有两者中的一个实际执行清理。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多