C# WPF Prsim PrsimOutlook学习记录(四)

最近在学习 Prsim 和WPF,在油管上找到了一个 PrsimOutlook 项目,作者是 Brian Lagunas ,是当年 Prsim 搬家到GitHub时交给社区的三位贡献者之一.

照着视频学习加上有源代码,视频作者就是Prsim的作者之一,对Prsim相当的了解,视频思路清晰,代码水平高,值得初学习.

以往文章链接

C# WPF Prsim PrsimOutlook学习记录(一)
C# WPF Prsim PrsimOutlook学习记录(二)
C# WPF Prsim PrsimOutlook学习记录(三)

相关链接

视频四 Creating a Service 学习记录

注:学习记录只是思路的整理,并没有把所有源码都贴在这里,具体源码可以看上方的链接下载

这节视频比较简单,主要是搭建了一个服务和填充了些数据
在这里插入图片描述
上一节已经将ContentRegion和RibbonRegion之前的导航和共享 DataContext完成了

首先现在 Business 项目中创建一个BusinessBase,继承 BindableBase

namespace PrismOutlook.Business
{
    public class BusinessBase :BindableBase
    {
    }
}

再创建一个MailMessage类,这个类里面有 邮件的属性,比如发送人,CC,To,Body,发送时间等属性,由于这些属性是需要Binding的,所以继承 BusinessBase

namespace PrismOutlook.Business
{
    public class MailMessage :BusinessBase
    {
        public int Id { get; set; }

		private string _from;

		public string From
		{
			get { return _from; }
            set { SetProperty(ref _from, value); }
        }

        private string _subject;
        public string Subject
        {
            get { return _subject; }
            set { SetProperty(ref _subject, value); }
        }

        private ObservableCollection<string> _to;
        public ObservableCollection<string> To
        {
            get { return _to; }
            set { SetProperty(ref _to, value); }
        }

        private ObservableCollection<string> _cc;
        public ObservableCollection<string>  CC   
        {
            get { return _cc; }
            set { SetProperty(ref _cc, value); }
        }

        private string _body;
        public string Body
        {
            get { return _body; }
            set { SetProperty(ref _body, value); }
        }

        private DateTime _dateSent;
        public DateTime DateSent
        {
            get { return _dateSent; }
            set { SetProperty(ref _dateSent, value); }
        }
    }
}

有了Model,现在需要一个服务,来提供数据
下面开始些Services的接口
Mail Module只需要调用 服务的接口,对具体的执行内容不需要关心

namespace PrsimOutlook.Services.Interfaces
{
    public interface IMailServices
    {
        IList<MailMessage> GetInboxItems();

        IList<MailMessage> GetSentItems();

        IList<MailMessage> GetDeletedItems();
    }
}

Service的具体数据的执行和Service的接口也不要放在一个项目里,这样写单元测试或者想更换的时候,随时更换
下面写 Service的实现
目前只填充了收件箱的数据

namespace PrsimOutlook.Services
{
    public class MailService : IMailServices
    {
        static List<MailMessage> InboxItems = new List<MailMessage>()
        {
            new MailMessage()
            {
                Id = 1,
                From = "jerrynixon@microsoft.com",
                To = new ObservableCollection<string>(){ "jane@doe.com", "john@doe.com" },
                Subject = "This is a test email",
                Body = "this is the body of an email",
                DateSent = DateTime.Now
            },
            new MailMessage()
            {
                Id = 2,
                From = "jerrynixon@microsoft.com",
                To = new ObservableCollection<string>(){ "jane@doe.com", "john@doe.com" },
                Subject = "This is a test email 2",
                Body = "this is the body of an email 2",
                DateSent = DateTime.Now.AddDays(-1)
            },
            new MailMessage()
            {
                Id = 3,
                From = "jerrynixon@microsoft.com",
                To = new ObservableCollection<string>(){ "jane@doe.com", "john@doe.com" },
                Subject = "This is a test email 3",
                Body = "this is the body of an email 3",
                DateSent = DateTime.Now.AddDays(-5)
            },
        };

        static List<MailMessage> SentItems = new List<MailMessage>() { };


        static List<MailMessage> DeletedItems = new List<MailMessage>() { };

        public IList<MailMessage> GetInboxItems()
        {
            return InboxItems;
        }

        public IList<MailMessage> GetSentItems()
        {
            return SentItems;
        }

        public IList<MailMessage> GetDeletedItems()
        {
            return DeletedItems;
        }


    }
}

之后我们要注入到MailModule中,因为我们不想让其他的Module知道 MailService的存在
在MailModule中

public void RegisterTypes(IContainerRegistry containerRegistry)
{
    ViewModelLocationProvider.Register<MailGroup, MainGroupViewModel>();
    containerRegistry.RegisterForNavigation<MailList, MailListViewModel>();


    //注册
    containerRegistry.RegisterSingleton<IMailServices, MailService>();
}

在MailListViewModel改写一下,获取服务的实例

namespace PrsimOutlook.Modules.Mail.ViewModels
{
    public class MailListViewModel : ViewModelBase
    {
        private readonly IMailServices _mailServices;
        private ObservableCollection<MailMessage> _messages;
        public ObservableCollection<MailMessage>  Messages
        {
            get { return _messages; }
            set { SetProperty(ref _messages, value); }
        }
        private MailMessage _selectedMessage;
        public MailMessage SelectedMessage
        {
            get { return _selectedMessage; }
            set { SetProperty(ref _selectedMessage, value); }
        }
        public MailListViewModel(IMailServices mailServices)
        {
            this._mailServices = mailServices;
        }
        public override void OnNavigatedTo(NavigationContext navigationContext)
        {
            //Title = navigationContext.Parameters.GetValue<string>("id");
            var floder = navigationContext.Parameters.GetValue<string>(FolderParameters.FolderKey);

            switch (floder)
            {
                case FolderParameters.Inbox:
                    Messages = new ObservableCollection<MailMessage>(_mailServices.GetInboxItems());
                    break;
                case FolderParameters.Sent:
                    Messages = new ObservableCollection<MailMessage>(_mailServices.GetSentItems());
                    break;
                case FolderParameters.Deleted:
                    Messages = new ObservableCollection<MailMessage>(_mailServices.GetDeletedItems());
                    break;
                default:
                    break;
            }      
        }    
    }
}

创建一下 FolderParameters类

    public class FolderParameters
    {
        public const string FolderKey = "Folder";

        public const string Inbox = "Inbox";
        public const string Sent = "Sent";
        public const string Deleted = "Deleted";
    }

重构一下 GenerateMenu方法

void GenerateMenu()
{
    Items = new ObservableCollection<NavigationItem>();
    /*var root = new NavigationItem() { Caption = "Personal Folder", NavigationPath = "MailList?id=Default" };
    root.Items.Add(new NavigationItem() { Caption = "Inbox", NavigationPath = "MailList?id=Inbox" });
    root.Items.Add(new NavigationItem() { Caption = "Deleted", NavigationPath = "MailList?id=Deleted" });
    root.Items.Add(new NavigationItem() { Caption = "Sent", NavigationPath = "MailList?id=Sent" });*/

    var root = new NavigationItem() { Caption = "Personal Folder", NavigationPath = "MailList?id=Default",IsExpended = true };
    root.Items.Add(new NavigationItem() { Caption = Resource.Folder_Inbox, NavigationPath = GetNavigationPath(FolderParameters.Inbox) });
    root.Items.Add(new NavigationItem() { Caption = Resource.Folder_Deleted, NavigationPath = GetNavigationPath(FolderParameters.Deleted) });
    root.Items.Add(new NavigationItem() { Caption = Resource.Folder_Sent, NavigationPath = GetNavigationPath(FolderParameters.Sent) });

    Items.Add(root);
}

string GetNavigationPath(string folder)
{
    return $"MailList?{FolderParameters.FolderKey}={folder}";
}

这里做了个本地化的操作
在这里插入图片描述
重新修改一下MailList.xaml

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="370"></ColumnDefinition>

            <ColumnDefinition Width="*"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Grid Background="White" Margin="5,0,0,0" >
            <ig:XamDataGrid DataSource="{Binding Messages}" ActiveDataItem="{Binding SelectedMessage}">
                <ig:XamDataGrid.FieldSettings>
                    <ig:FieldSettings AllowEdit="False"/>
                </ig:XamDataGrid.FieldSettings>
                
                <ig:XamDataGrid.FieldLayoutSettings>
                    <ig:FieldLayoutSettings AutoGenerateFields="False"></ig:FieldLayoutSettings>
                </ig:XamDataGrid.FieldLayoutSettings>
                <ig:XamDataGrid.FieldLayouts>
                    <ig:FieldLayout>
                        <ig:TextField Name="From"></ig:TextField>
                        <ig:TextField Name="Subject"></ig:TextField>
                        <ig:DateTimeField Name="DateSent"></ig:DateTimeField>
                    </ig:FieldLayout>
                </ig:XamDataGrid.FieldLayouts>
               
            </ig:XamDataGrid>
        </Grid>
        

        <!--Mail Preview Area-->
        <Border Grid.Column="1" Margin="5,0,0,0" Background="White">
            <StackPanel>

                <TextBlock Margin="5" Text="{Binding SelectedMessage.From}"/>
                <TextBlock Margin="5" Text="{Binding SelectedMessage.To}"/>
                <TextBlock Margin="5" Text="{Binding SelectedMessage.CC}"/>
                <TextBlock Margin="5" Text="{Binding SelectedMessage.Subject}"/>
                <TextBlock Margin="5" Text="{Binding SelectedMessage.From}"/>
                <TextBlock Margin="5" Text="{Binding SelectedMessage.Body}"/>
            </StackPanel>
        </Border>

        <GridSplitter Grid.Column="1" VerticalAlignment="Stretch"  Width="10" HorizontalAlignment="Left"  Grid.RowSpan="100">
            <GridSplitter.Template>
                <ControlTemplate>
                    <Grid Background="White">
                        <Rectangle Width="1" Fill="#D4D4D4" Margin="0,5,0,0" HorizontalAlignment="Center"/>
                    </Grid>
                </ControlTemplate>
            </GridSplitter.Template>
        </GridSplitter>
    </Grid>

这样程序启动,就可以完成程序开始程序的功能了
还有一个程序一打开默认显示在Inbox上
在MailGroup中 写一下这个

public MailGroup()
{
    InitializeComponent();
    _dataTree.Loaded += DataTree_Loaded;
}

private void DataTree_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
    _dataTree.Loaded -= DataTree_Loaded;

    var parentNode = _dataTree.Nodes[0];
    var nodeToSelect = parentNode.Nodes[0];
    nodeToSelect.IsSelected = true;
}
总结

这节主要是搭建了服务,填充了数据.修改了一下MailList.xaml的界面显示.还有重构了一下导航的参数部分.

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值