本文来自:Recommendations and best practices for implementing MVVM and XAML/.NET applications

项目的文件(目录)结构

项目的文件结构

  • App.xaml
  • Controls: 重复使用的 UI(没有 ViewModel)
  • Localization: 用于程序本土化的类代码和资源文件
  • Models: Model and domain classes
  • ViewModels: View models classes
    • MainWindowModel.cs
    • MyViewModel.cs
    • Dialogs
      • SelectItemDialogModel.cs
  • Views: Contains the views
    • MainWindow.xaml
    • MyView.xaml
    • Dialogs
      • SelectItemDialog.xaml

View 的名称体是以它的类型(Window、View、Dialog)结尾的;ViewModel 的名称是 View名称 + Model 后缀(例如:MainWindow – MainWindowModel)。

View – ViewModel 原则

View – ViewModel 是一一对应的关系,只有 View 才能访问它的 ViewModel,别的 View 不能访问其它的 ViewModel。

ViewModel 不能直接访问它的 View,只能通过 messenger (或其它 IoC 机制)实现方法 调用。

如果 View 很大(复杂),应该把它拆分成多个 View。

ViewModel 的实例化和赋值

在 XAML 里以根元素 Resources 方式实例化 ViewModel,然后再分配给顶级子元素的 DataContext,像这样:

 <UserControl x:Class="My.Namespace.MySampleView" ...> 
    <UserControl.Resources> 
        <viewModels:MySampleViewModel x:Key="ViewModel" /> 
    </UserControl.Resources> 

    <Grid DataContext="{StaticResource ViewModel}"> 
        ... 
    </Grid> 
</UserControl> 

如果需要在 View 中访问 ViewModel,那么可以在 .xaml.cs 中这样实现:

 protected MySampleViewModel Model 
{
    get { return (MySampleViewModel)Resources["ViewModel"]; } 
}

这样做的好处是:

  • Visual Studio 的编辑器能识别到 Resource 的类型,这样就可以提供 IntelliSense 功能
  • 其它 UI 需要 ViewModel 的内容时,可以很方便通过 Resource 的 key 来访问。

不要在 View 实例化的地方设置 DataContext 属性, 只有 View 自己才能给它的 DataContext 赋值。 如下做法是错的:

<MySubView DataContext="{Binding MySubViewModel}" />

根元素需要绑定 ViewModel 属性怎么办

因为 ViewModel 只有在 Resources 之后才可用,所以我们就无法直接在根元素上使用属性绑定,需要换种方式,像这样:

 <Window ...> 
    <Window.Resources> 
        <viewModels:MyWindowModel x:Key="ViewModel" /> 
    </Window.Resources> 
    <Window.Title> 
        <Binding Source="{StaticResource ViewModel}" Path="Document.Title" /> 
    </Window.Title> 

    ...  

Command 实现

所有 UI 动作都在 ViewModel 中以 Command 实现 。

使用 Dependency Property 来给 View 传参

Dependency Property 这样实现:

public class MySubView
{
    public static readonly DependencyProperty ProjectProperty = DependencyProperty.Register( 
        "Project", typeof(Project), typeof(MySubView),  
        new PropertyMetadata(default(Project), OnProjectChanged)); 

    public Project Project 
    { 
        get { return (Project)GetValue(ProjectProperty); } 
        set { SetValue(ProjectProperty, value); } 
    } 

    private static void OnProjectChanged(DependencyObject obj,  
        DependencyPropertyChangedEventArgs args) 
    { 
        ((MySubView)obj).Model.Project = (Project)args.NewValue; 
    }  

    public ProjectPropertiesViewModel Model 
    { 
        get { return (ProjectPropertiesViewModel)Resources["ViewModel"]; } 
    } 
}

然后,在 xaml 中可以这样传参:

<MySubView Project="{Binding SelectedProject}" />

ViewModel 的生命周期

View 调用 ViewModel 的相关方法:

public MyView() 
{ 
    InitializeComponent(); 
    Model.Initialize();    
    Loaded += delegate { Model.OnLoaded(); }; 
    Unloaded += delegate { Model.OnUnloaded(); }; 
}

ViewModel 实现:

public class MyViewModel  
{ 
    private bool _isLoaded = false;  

    public MyViewModel()
    {
        // TODO: Add your constructor code here
        // The ctor is always called, initialize view model so that it also works in designer
    }

    public void Initialize()
    {
        // TODO: Add your initialization code here 
        // This method is only called when the application is running
    }

    public void OnLoaded() 
    { 
        if (!_isLoaded) 
        { 
            // TODO: Add your loaded code here 
            _isLoaded = true;  
        } 
    } 

    public void OnUnloaded() 
    { 
        if (_isLoaded) 
        { 
            // TODO: Add your cleanup/unloaded code here 
            _isLoaded = false; 
        } 
    }
    ... 

注意,我们在 xaml 中实例化了 ViewModel,这样 ViewModel 的构造函数在 Visual Studio 编辑器中就会被执行,没必要让代码在设计阶段就执行,所以我们独立出了 Initialize 方法。

XAML 的绑定一定要声明类型

这一条很重要:XAML 里的所有绑定(Binding)都要声明类型,通常在 Resources 会声明类型的,但是如果有其它的绑定方式,一定要手动声明绑定的类型:

<Window xmlns:MyNamespace="clr-namespace:MyNamespace"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"  
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        mc:Ignorable="d"
        ...>
    ... 
    <StackPanel d:DataContext="{d:DesignInstance Type=MyNamespace:MyType}"> 
        ... 
    </StackPanel> 

如果使用 WordPress multi site 功能的话,你会发现 administrator 账号是缺少安装插件的权限的,必须要 super admin 才行。通过数据库可以直接把账号提升到 super admin 权限,需要操作 *sitemeta 表,给 meta_key=site_admin 的 meta_value 加入账号名即可。

通过 curl 发送 cookie ,可以使用 –cookie 参数,请点击

还可以通过 -H 设置 Header 来实现的,比如:

 

可以使用 php_flag 来禁止 php 的执行

除了 php_flag 外,还可以通过 RemoveHander 和 RemoveType 来禁用 php 执行:

还可以通过 SetHandler 和 ForceType:

 

  1. 基本上 attrib 设置文件夹的“只读”是无效的,或者说,attrib 设置的这个“只读”和我们预想的(不能在文件夹内创建文件)是完全不一样的。attrib 对应于“属性”窗口 – “常规”。
  2. 真正要让文件夹“只读”,你需要做的是正确设置用户的权限,比如某个用户在这个文件夹只有“读取”的权限,你可以通过 icalcs 来做到,对应于“属性”窗口 – “安全”。

先看下这个问题

有两个文件 a.txt 和 b.txt
a.txt:

b.txt:

你需要能输出 b.txt 里没有在 a.txt 中的行:

最简单的方法是使用 Windows 的 findstr 命令

是不是超级简单的,参数请参考这里

如果需要使用 document.querySelector 选择勾选的 checkbox 你会怎么做?是不是这样:

看上去没错,但你要清楚 attribute 和 property 的区别,attribute 指的是最初声明在 HTML(源码)中的属性,通过 JS 或点击改变的是 input.checked 这个 property。

所以更安全的写法是用 : 指定 property:

 

最重要的是要有耐心,一步一步来,注册完 paxum.com 的后,账号(应该)是激活状态的,不影响收款。接下来要做的就是让账号验证通过,就可以提现了。

回想起来,这个过程其实并不难,对未知的恐惧才是你最大的障碍。记住,一定要有耐心。

  1. 身份证明(Proof Of Identity)
    • 办护照
      带上你的身份证,到你户口所在地的出入境管理部门办理。现在政府部门办事效率也改善很多了,进入大厅询问工作人员,然后填表、拍照、交款,填写邮寄地址。9 个工作日内,你会收到短信通知 EMS 包裹状态。
      总之,要有耐心,不要因为已有(办证)经验就不耐烦,就情绪不好,就火冒三丈。
    • 填写身份证明(Proof Of Identity)
      1. 先到文印店,扫描一下你的护照(有你照片的那一页)。
      2. 到 paxum.com 上填表单
        注意你填写的内容不能有任何中文。
        series 这一栏填 N/A 即可,Issuing Authority (签发机关)要填护照上英文信息(MPS Exit & Entry Administration)。其它的就对护照上的信息填。
      3. 上传你扫描的护照图片。
      4. 等待身份证明通过
        你提交的身份证明状态变成 Validated 即可。
      5. 如果身份证明很久没通过(2个工作日以上?),就在
        Message Center 里 Open ticket 向  paxum.com 工作人员询问。
  2. 地址证明(Proof Of Address)
    1. 你地址的英文格式
      paxum.com 需要的地址格式是这样的:

      Street Name, Street Number, Building, Entrance, Floor, Apartmen, District, City, State, China, Postal code

      翻译成中文就是:

      街道(路、大道), 街道门牌号, 哪栋楼, 入口(什么鬼?),  楼层,  室, 哪个区, 城市,  省, 国家, 邮编

      把你的地址按照这个格式写一下。

    2. 在 paxum.com 账号增加一个地址
      打开 paxum.com 填写地址的网页,
      填好,保存。地址好了,不过还没对它进行验证。
    3. 认证你的地址
      地址证明的上面必须有你的名字(英文/拼音)和地址(英文/拼音),这个地址证明必须有公信力,可以是信用卡账单、水电煤气账单等等。
      我的选择是:建设银行信用卡账单。思路是:把账单地址改成中英文(拼音)结合的,让银行寄给我,然后拍照,上传到 paxum.com 证明地址。

      1. 修改账单地址
        打开建设银行的手机 APP,信息卡,个人资料,修改账单地址。

        姓名和地址要填英文(拼音)格式,特别要注意的是账单地址,为确保能收到邮寄的账单,我填的账单地址是中文 + 英文(拼音)结合的。
      2. 寄账单
        直接打电话给客服,要求补寄账单。注意,现在银行都会有电子账单和邮寄账单。你一定要问清楚,电子账单上会不会有你的地址信息?如果有,那直接要求发你邮箱就;如果没有,就需要邮寄账单。

        • 建设银行的电子账单不念有地址信息,而且修改的账单地址要次月才会生效。所以我还得再等等。
        • 招商银行的电子账单包含有地址信息。
      3. 提交账单图片
        终于我收到账单了,并上面有我的英文地址。
        拍照留存后,赶紧提交给 paxum 验证地址,不久之后我就收到了账号完成验证的邮件:

如你所见,不难,但办证要时间,邮寄要时间,和 paxum 交流要时间,这些急是没有用的,最需要的是耐心。

很多时候,为了安全,我们的 php 是不允许被直接访问的(这些文件应该被 include 在其它文件中的),可以在 php 开始处贴上这行代码,限制