Windows 8 metro app 记事本

本项目已经开源,项目地址: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文件中内容如下:


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值