从设置弹出窗口更新2个不同的类?

时间:2013-05-23 13:26:39

标签: c# windows-8 settings flyout

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

在我的应用中,我需要一个重置选项,将应用程序置于默认设置。有两个页面,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)的第一页中按下Reset时,首先调用第一页(Calendar.xaml.cs)中声明的重置单击函数,然后调用HistoryStatistics中的重置函数。两者都被执行异步! :( 这是正确的行为吗?

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

2 个答案:

答案 0 :(得分:1)

您概述的行为没有任何问题。两个页面订阅一个事件,事件使用多播委托,这意味着他们都会被解雇。

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

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

答案 1 :(得分:0)

由于未使用MVVM(模型,视图和视图模型)分离,可能会出现复杂性/混淆。你可能想读一下这个。保持分离有帮助。以下是对此的一些指示。但不一定是您应用的完整设计。

在这个例子中

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

// 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事件处理程序并采取必要的操作。他们不需要调用设置mgr来初始化值。

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。