This project has been open source, Project address: https://github.com/GinSmile/PopDiary
This application is a Windows Store application developed using C # And XAML technologies. It meets the audit requirements of Microsoft app store. The interface is simple and easy to use and can meet the requirements of general users for the notebook.
Development Environment
Operating System: Windows 8
Development tools: Visual Studio 2012
I. Functional Design
The function diagram of this application is as follows:
II. Application Structure
The document structure is as follows:
Where,
- Mainpage. XAML is the login interface. The program jumps directly from the splashscreen to this interface.
- Index. XAML is a directory page that displays all the diary directories.
- Diarydetail. XAML allows you to edit a diary on the editing page.
- Usersetting. XAML is the password modification page.
- About. XAML is about the interface
Detailed story versions such:
Iii. Functional Module Design
3.1 login module
This module corresponds to the mainpage. XAML interface file and mainpage. XAML. CS file in the project file.
The core code of the interface is as follows:
<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>
As follows:
Core logic code:
Mainpage. XAML. CS |
If you click the arrow, the system checks whether the password is correct. If yes, the log directory page is displayed. Otherwise, the tips content is changed. This Code uses the windows. Storage. applicationdatacontainer class to permanently store data. You can also modify the password. For more information about the code, see other sections of this article. |
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 = "The original password is" + currentPassword;
localSettings.Values["passwordData"] = "12345";
}
Else
{
tips.Text = "Please enter a password";
currentPassword = localSettings.Values["passwordData"].ToString();
}
}
Private void check_button(object sender, RoutedEventArgs e)
{
If (thePassBox.Password == currentPassword)
{
tips.Text = "Password is correct";
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 Directory Module
This module corresponds to the mainpage. XAML interface file and mainpage. XAML. CS file in the project file.
The core code of the interface is as follows:
Mainpage. XAML |
The interface of this module is mainly a gridview, which stores the diary directory. each item is composed of two parts, that is, two textbloks. Bind the time and content in the log information respectively. |
<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>
Core logic code:
Mydiary. CS |
The Code defined by the mydiary class implements the inotifypropertychanged interface and defines two string-type variables. After binding, changes to the mydiary object can be reflected on the interface. |
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;
}
Initialization (index. XAML. CS) |
Override the onnavigatedto function, which is triggered when the program is directed to this page. In this program, it checks whether the application is accessed for the first time (using the localsettings. Values ["first"] key-Value Pair ). When it is determined that it is the first visit, add an initial diary to introduce this program, otherwise load the user's previous diary information. |
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)
{
// The first time you enter, there is no data in the program;
myIndex = new ObservableCollection<MyDiary>();
myIndex.Add(new MyDiary { Time = getNow(), Content = "Welcome to Pop Diary. You can use it to record your every day." });
}
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;
}
}
Data storage function (index. XAML. CS) |
The storedata () function stores the log-related data in 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 Add a diary
Add a diary (index. XAML. CS) |
Addnewdiary () is used to add a diary. It is triggered by clicking the Add diary button. This function transfers a diary type object to the diarydetail page. |
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);
}
Click a diary and navigate to the editing page (index. XAML. CS) |
Clicking on any project in the gridview will trigger this event and a parameter will be passed. This parameter is an object of the object type and can be converted to diary = (mydiary) navigationparameter on the diarydetail page; |
private void Index_ItemClick(object sender, ItemClickEventArgs e)
{
this.Frame.Navigate(typeof(DiaryDetail), e.ClickedItem);
}
3.4 delete a module
Delete function (index. XAML. CS) |
When a log is selected, the Select function is triggered to change the value of indexnum. This value indicates the number of the log, which is processed by the program. |
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("Are you sure to delete all diaries?");
md.Commands.Add(new UICommand("OK", command =>
{
myIndex.Clear();
}));
md.Commands.Add(new UICommand("cancel", command =>
{
//do nothing
}));
Await md.ShowAsync();
storeData();
}
3.5 export module
This module corresponds to the index. XAML. CS file in the project file, and the icon button is in the AppBar.
Export function (index. XAML. CS) |
Click the export as TXT text button to trigger this event and store all the data stored in the application in a TXT file. |
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("save success");
Await md.ShowAsync();
}
Else
{
MessageDialog md = new MessageDialog("Save unsuccessful");
Await md.ShowAsync();
}
}
}
}
:
Open the file after saving the file. The content of mydiary. and XT is as follows: