本項目已經開源,項目地址:https://github.com/GinSmile/PopDiary
本應用程式是使用c#和xaml技術開發的windows store application,滿足微軟市集審核條件,介面美觀簡潔,操作簡單,可以滿足一般使用者對日記本的要求。
開發環境
作業系統:Windows 8
開發工具:Visual Studio 2012
一、功能設計
本應用程式的功能圖如下:
二、應用結構
文件引導模式如下:
其中,
- MainPage.xaml是登陸介面,程式從splashscreen直接跳轉到這一個介面上。
- Index.xaml是目錄頁面,顯示所有日記目錄。
- DiaryDetail.xaml是編輯介面可以編輯日記。
- UserSetting.xaml是修改密碼的頁面。
- About.xaml是關於介面
詳細故事版如:
三、各功能模組設計
3.1 登陸模組
本模組對應工程檔案中的MainPage.xaml介面檔案和MainPage.xaml.cs檔案。
介面核心代碼如下:
<Grid > <Grid.Background> <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> <GradientStop Color="Black" Offset="0.004"/> <GradientStop Color="#FF0BADF9" Offset="0.746"/> </LinearGradientBrush> </Grid.Background> <Grid.RowDefinitions> <RowDefinition Height="140"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid Margin="-220,-117,-30,127" Grid.RowSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="1616"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button x:Name="go" AutomationProperties.Name="" Grid.Column="1" HorizontalAlignment="Left" Margin="1120,372,0,0" VerticalAlignment="Top" Style="{StaticResource NextAppBarButtonStyle}" Click="check_button" Height="66" Width="91"/> <PasswordBox x:Name="thePassBox" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center" Width="265" Margin="850,389,501,336" Height="33" Opacity="0.9" IsPasswordRevealButtonEnabled="True"/> <Image x:Name="icon" Grid.ColumnSpan="2" Height="218" Margin="0,327,802,0" VerticalAlignment="Top" Source="Assets/account.png" HorizontalAlignment="Right" Width="218" Opacity="0.88"/> <TextBlock x:Name="tips" Grid.Column="1" HorizontalAlignment="Left" Margin="850,444,0,0" TextWrapping="Wrap" Text="tips" VerticalAlignment="Top" Height="23" Width="152" FontSize="11"/> <TextBlock Grid.Column="1" HorizontalAlignment="Left" Margin="850,327,0,0" TextWrapping="Wrap" VerticalAlignment="Top" FontSize="33" Width="247" Height="57"> <Run Text="Password"/> <LineBreak/> <Run/> </TextBlock> </Grid> </Grid>
如下:
核心邏輯代碼:
MainPage.xaml.cs |
如果點擊了箭頭按鈕之後就會檢驗密碼是否正確,若正確,則進入日記目錄介面,否則更改tips的內容。本段代碼用到了Windows.Storage.ApplicationDataContainer類來完成資料的永久儲存。當然也可以完成密碼修改,具體代碼見本文其它部分。 |
public sealed partial class MainPage : Page { Windows.Storage.ApplicationDataContainer localSettings; public string currentPassword; public MainPage() { this.InitializeComponent(); localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; Object value = localSettings.Values["passwordData"]; if (value == null) { currentPassword = "12345"; tips.Text = "原始密碼為" + currentPassword; localSettings.Values["passwordData"] = "12345"; } else { tips.Text = "請輸入密碼"; currentPassword = localSettings.Values["passwordData"].ToString(); } } private void check_button(object sender, RoutedEventArgs e) { if (thePassBox.Password == currentPassword) { tips.Text = "密碼正確"; Frame.Navigate(typeof(Index)); } else { tips.Text = "Wrong password, please input again."; } } private void userSetting_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(UserSetting)); } private void about_Click(object sender, RoutedEventArgs e) { this.Frame.Navigate(typeof(About)); } }
3.2 目錄模組
本模組對應工程檔案中的MainPage.xaml介面檔案和MainPage.xaml.cs檔案。
介面核心代碼如下:
MainPage.xaml |
本模組的介面主要是一個GridView,裡面存放日記的目錄,每個item由兩部分組成,即兩個TextBlok。分別綁定日記資訊中的時間Time和內容Content。 |
<Grid Background="{StaticResource GridImageBrush}" > <GridView Name="IndexView" ScrollViewer.VerticalScrollBarVisibility="Auto" IsItemClickEnabled="True" SelectionMode="Single" Height="554" Margin="120,163,0,0" VerticalAlignment="Top" ItemClick="Index_ItemClick" HorizontalAlignment="Left" Width="1246" SelectionChanged="select"> <GridView.ItemTemplate> <DataTemplate> <StackPanel Name="myItem" Orientation="Vertical" Height="250" Width="200" Background="#FF00B7EF"> <TextBlock Text="{Binding Time}"></TextBlock> <TextBlock TextWrapping="Wrap" Text="{Binding Content}"></TextBlock> </StackPanel> </DataTemplate> </GridView.ItemTemplate> </GridView> <Image HorizontalAlignment="Left" Height="91" Width="423" Source="Assets/splshScreenNoBar.png" Margin="120,57,0,620"/> <Button x:Name="AddDiary" HorizontalAlignment="Left" Margin="1109,64,0,0" VerticalAlignment="Top" Click="AddNewDiary" Style="{StaticResource AddAppBarButtonStyle}"/> </Grid>
核心邏輯代碼:
MyDiary.cs |
MyDiary類定義的代碼,實現了INotifyPropertyChanged介面,定義了兩個string類型的變數,在綁定之後可將對MyDiary對象的更改反映到介面上。 |
public class MyDiary : INotifyPropertyChanged { private string _time; private string _content; public string Time { get { return _time; } set { _time = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Time")); } } } public string Content { get { return _content; } set { _content = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Content")); } } } public override string ToString() { return "Time:" + Time + "\nContent:" + Content; } public event PropertyChangedEventHandler PropertyChanged; }
初始化(Index.xaml.cs) |
重寫OnNavigatedTo函數,當程式導航到本頁面的時候觸發。在此程式中,實現了檢驗是否第一次訪問該應用程式(使用localSettings.Values["first"]這個索引值對)。當確定是第一次訪問的時候,添加進去一篇初始的日記來介紹本程式,否則載入使用者之前的日記資訊。 |
Static ObservableCollection<MyDiary> myIndex; static Windows.Storage.ApplicationDataContainer localSettings = Windows.Storage.ApplicationData.Current.LocalSettings; static Windows.Storage.ApplicationDataContainer container = localSettings.CreateContainer("diaryContainer", Windows.Storage.ApplicationDataCreateDisposition.Always); protected override void OnNavigatedTo(NavigationEventArgs e) { if (e.NavigationMode == NavigationMode.New) { // Composite setting if (localSettings.Values["first"] == null) { // 第一次進入,程式裡面沒有資料; myIndex = new ObservableCollection<MyDiary>(); myIndex.Add(new MyDiary { Time = getNow(), Content = "歡迎使用Pop Diary(泡泡日記本).您可以使用它來記錄你的每一天。" }); } else { if (localSettings.Containers.ContainsKey("diaryContainer")) { myIndex = new ObservableCollection<MyDiary>(); int length = int.Parse(localSettings.Containers["diaryContainer"].Values["length"].ToString()); for (int i = 0; i < length; i++ ) myIndex.Add(new MyDiary { Time = localSettings.Containers["diaryContainer"].Values["time" + i].ToString(), Content = localSettings.Containers["diaryContainer"].Values["content" + i].ToString() }); } } IndexView.ItemsSource = myIndex; } }
儲存資料功能(Index.xaml.cs) |
storeData()函數,把日記相關資料存放區到localSettings中。 |
static public void storeData() { if (myIndex != null) { int length = myIndex.Count; localSettings.Containers["diaryContainer"].Values["length"] = length; for (int i = 0; i < length; i++) { localSettings.Containers["diaryContainer"].Values["time" + i] = myIndex.ElementAt(i).Time; localSettings.Containers["diaryContainer"].Values["content" + i] = myIndex.ElementAt(i).Content; } localSettings.Values["first"] = "false"; } }
3.3添加日記
添加日記功能(Index.xaml.cs) |
AddNewDiary()函數,用來添加日記用的,點擊添加日記按鈕後觸發,該函數傳遞一個Diary類型的對象給DiaryDetail頁面。 |
private void AddNewDiary(object sender, RoutedEventArgs e) { string now = getNow(); MyDiary diary = new MyDiary { Time = now, Content = " " }; myIndex.Insert(0, diary); storeData(); this.Frame.Navigate(typeof(DiaryDetail), diary); }
點擊某個日記導航到編輯頁面(Index.xaml.cs) |
點擊GridView中的任何一個項目,都會觸發這個事件,並且會傳遞一個參數,該參數為Object類型的對象,可以在DiaryDetail頁面中轉化為diary = (MyDiary)navigationParameter; |
private void Index_ItemClick(object sender, ItemClickEventArgs e) { this.Frame.Navigate(typeof(DiaryDetail), e.ClickedItem); }
3.4 刪除模組
刪除功能(Index.xaml.cs) |
當選中一個日記的時候會觸發select函數,從而改變indexNum的值,這個值代表這個日記的標號,程式根據這個標號來對日記進行處理。 |
int indexNum = 0; private void select(object sender, SelectionChangedEventArgs e) { indexNum = IndexView.SelectedIndex; ...... } private void remove_Click(object sender, RoutedEventArgs e) { myIndex.RemoveAt(indexNum); remove.Visibility = Windows.UI.Xaml.Visibility.Visible; removeAll.Visibility = Windows.UI.Xaml.Visibility.Visible; storeData(); } private async void removeAll_Click(object sender, RoutedEventArgs e) { MessageDialog md = new MessageDialog("確定刪除所有日記?"); md.Commands.Add(new UICommand("確定", command => { myIndex.Clear(); })); md.Commands.Add(new UICommand("取消", command => { //do nothing })); await md.ShowAsync(); storeData(); }
3.5匯出模組
本模組對應工程檔案中的Index.xaml.cs檔案,表徵圖按鈕在Appbar中。
匯出功能(Index.xaml.cs) |
點擊匯出為txt文本按鈕,就會觸發這個事件,把應用程式儲存中的所有資料都儲存一個txt檔案中。 |
private async void export_Click(object sender, RoutedEventArgs e) { if(this.EnsureUnsnapped()){ FileSavePicker savePicker = new FileSavePicker(); savePicker.SuggestedStartLocation = PickerLocationId.DocumentsLibrary; savePicker.FileTypeChoices.Add("Plain Text", new List<string>() { ".txt" }); savePicker.SuggestedFileName = "MyDiary"; StorageFile file = await savePicker.PickSaveFileAsync(); if (file != null) { CachedFileManager.DeferUpdates(file); string theAllDiary = ""; foreach (MyDiary s in myIndex) { theAllDiary += s.Time + Environment.NewLine + s.Content + Environment.NewLine + Environment.NewLine; } await FileIO.WriteTextAsync(file, theAllDiary); FileUpdateStatus status = await CachedFileManager.CompleteUpdatesAsync(file); if (status == FileUpdateStatus.Complete) { MessageDialog md = new MessageDialog("儲存成功"); await md.ShowAsync(); } else { MessageDialog md = new MessageDialog("儲存未成功"); await md.ShowAsync(); } } } }
:
儲存之後開啟該檔案,MyDiary.,xt檔案中內容如下: