[英]Update 2 different classes from a settings flyout?
根據MSDN指南,我們需要將所有應用程序設置都放入SettingsPane中,然后應用該設置時,應用程序應該更新所有頁面。
在我的應用程序中,我需要有一個重置選項,該選項將應用程序恢復為默認設置。 按下重置按鈕時,我需要更新2個頁面,Calendar.xaml和HistoryStatistics.xaml。 該應用程序的所有數據都放在一個名為CycleManager的單例類中。 我使用了Callisto工具包中的SettingsFlyout控件。
應用程式
在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
}
}
現在的問題
這是正確的方法嗎?
在第二頁(HistoryStatistcs)的第一頁中按下“重置”時,在第一頁(Calendar.xaml.cs)中聲明的單擊重置的函數將首先被調用,然后在HistoryStatistics中被調用。 兩者都被異步執行! :(這是正確的行為嗎?
這個問題很長。 希望每個人都了解情況和問題。
您概述的行為沒有任何問題。 兩個頁面訂閱一個事件,並且事件使用多類型委托,這意味着它們都會被觸發。
我認為您在這里需要一個更簡單的行為。 每個xaml頁面都應在OnNavigatedTo上訂閱該事件,並應在OnNavigatedFrom中退訂。
這樣,實際上只有兩者之一執行清除。
由於未使用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事件處理程序並采取所需的操作。 他們不需要調用設置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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.