10

INotifyPropertyChanged のこのコード スニペットを見つけました

しかし、それは次のようなコードを示しています:

INotifyPropertyChanged

私はこれを持っているでしょう:

  1. public : 最初の文字の大文字 + ...

  2. 個人用 : アンダースコア + 最初の文字の小文字 + ...

どうすればこれを達成できますか?

編集:パブリックフィールドとプライベートフィールドを入力する必要なし

<Snippet>
    <Declarations>
        <Literal>
            <ID>type</ID>
            <ToolTip>Property type</ToolTip>
            <Default>string</Default>
        </Literal>
        <Literal>
            <ID>property</ID>
            <ToolTip>Property name</ToolTip>
            <Default>MyProperty</Default>
        </Literal>
        <Literal>
            <ID>notifyMethod</ID>
            <ToolTip>name of method to raise PropertyChanged event</ToolTip>
            <Default>NotifyPropertyChanged</Default>
        </Literal>
    </Declarations>
    <Code Language="csharp">
        <![CDATA[private $type$ _$property$;
            public $type$ $property$
            {
                get { return _$property$;}
                set 
                { 
                    if (value != _$property$)
                    {
                        _$property$ = value;
                        $notifyMethod$("$property$");
                    }
                }
            }
        $end$]]>
    </Code>
</Snippet>
4

5 に答える 5

16

スニペットは xml で記述でき、vs の任意の言語用に作成できます

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <Header>
    <Title>Notify Property Changed Method</Title>
    <Author>Akash</Author>
    <Shortcut>npcm</Shortcut>
    <Description>This method implements the OnPropertyChanged method and binds to the event handler</Description>
    <SnippetTypes>
      <SnippetType>SurroundsWith</SnippetType>
      <SnippetType>Expansion</SnippetType>
    </SnippetTypes>
  </Header>
  <Snippet>

    <Code Language="CSharp">
      <![CDATA[#region Notify Property Changed Members
  public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if(handler!=null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }    
        #endregion]]>
    </Code>
  </Snippet>
</CodeSnippet>

これは、notify プロパティの変更メソッドを自動的に生成するコードです。Documents/VisulaStudio(YourVersion)/Code Snippets/Visual C#/ にスニペットとして拡張子を付けて、これを単一のファイルに保存するだけです。

それはあなたがそれを使用する準備ができていることです...

ここで、ショートカット タグがあるコード スニペットを観察します。このタグは、スニペットをアクティブにするために書き込み中に vs で使用する必要があるタグを参照します。

プロパティ自体のコードは次のとおりです。

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippet Format="1.0.0" xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <Header>
    <Title>Notifiable Property</Title>
    <Author>Akash</Author>
    <Shortcut>nprop</Shortcut>
    <Description>Property With in Built Property Changed method implementation.</Description>
    <SnippetTypes>
      <SnippetType>SurroundsWith</SnippetType>
      <SnippetType>Expansion</SnippetType>
    </SnippetTypes>
  </Header>
  <Snippet>
    <Declarations>
      <Literal>
        <ID>Type</ID>
        <Default>string</Default>
      </Literal>
      <Literal>
        <ID>Property</ID>
        <Default>PlaceHolder</Default>
      </Literal>
    </Declarations>
    <Code Language="CSharp">
      <![CDATA[private $Type$ _$Property$;
        public $Type$ $Property$
        {
            get { return _$Property$; }
            set { 
               if(value!=null || value != _$Property$) _$Property$ = value;
               OnPropertyChanged("$Property$");
            }
        }]]>
    </Code>
  </Snippet>
</CodeSnippet>

この特定のスニペットでは、 nprop と入力してタブタブを押すだけで、必要なコードが生成されます..データ型と名前を入力するだけで済みます..残りはスニペット自体によって処理されます...

これはより優れたソリューションであり、コーディング速度が大幅に向上しますが、これは小規模なプロジェクトにのみ適していますが、viewmodelbase メソッドは大規模なプロジェクトに適しています。

于 2015-06-18T15:40:46.730 に答える
2

残念ながら、これはコード スニペットを使用して行うことはできません。

必要なものは、変換する$property$か、その他のリテラルにする必要があります。プロパティ名を 2 つの部分 (最初の文字と残りの文字) に分割したとしても、文字を大文字にする必要があります (または逆に小文字にする必要があります)。

スニペットが提供する変換関数の数は非常に限られています。C# の場合は正確に 3 つですが、必要な結果を得ることができる関数は 1 つもありません。MSDN のコード スニペット関数を参照してください。これは、2013 年までのすべてのバージョンの Visual Studio に当てはまります。

于 2013-11-10T06:06:08.523 に答える
1

聞きたくない答えを教えます。これを行う必要はまったくありません。モデルには (full または auto) プロパティが必要であり、ViewModel プロパティには getter と を返す setter のみが必要_model.MyPropertyです。

CallerMemberNameまた、その厄介な魔法の糸を取り除くために調べたいと思うかもしれません. 必要に応じて、いくつかの例を投稿します。


たとえば、DealsUserモデル クラスがあります (電子メール アドレスが明示的に設定されていない場合に電子メール アドレスを生成するなどの内部ロジックがここでどのように行われるかに注意してください)。

public class DealsUser : IDealsUser
{
    public DealsUser() : this("GUEST")
    {
    }

    public DealsUser(string username)
    {
        this.Username = username;
        this.IsAdministrator = false;
        this.IsPlanModerator = false;
        this.IsPlanner = false;
    }

    public string Username { get; set; }

    public bool IsAdministrator { get; set; }

    public bool IsPlanModerator { get; set; }

    public bool IsPlanner { get; set; }

    private string _emailAddress;
    public string EmailAddress
    {
        get
        {
            return _emailAddress ?? string.Format(
                "{0}@mycompany.co.za", this.Username);
        }
        set
        {
            _emailAddress = value;
        }
    }

    public override string ToString()
    {
        return this.Username;
    }

そしてBaseViewModel、次のイベントと保護されたメソッドを持つクラスがあります (CallerMemberName魔法の文字列を削除するために使用する方法に注意してください)。

#region INotifyPropertyChanged Members

public event PropertyChangedEventHandler PropertyChanged;

protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    var eventHandler = this.PropertyChanged;
    if (eventHandler != null)
    {
        eventHandler(this, new PropertyChangedEventArgs(propertyName));
    }
}

protected bool SetProperty<T>(ref T storage, T value,
    [CallerMemberName] string propertyName = null)
{
    if (object.Equals(storage, value))
    {
        return false;
    }

    storage = value;
    this.OnPropertyChanged(propertyName);
    return true;
}

protected bool SetModelProperty<T>(T storage, T value, Action setter,
    [CallerMemberName] string propertyName = null)
{
    if (object.Equals(storage, value))
    {
        return false;
    }

    setter();
    this.OnPropertyChanged(propertyName);
    return true;
}

#endregion

次に、から継承しBaseViewModel、モデルをコンストラクターに依存関係として挿入し、ViewModelをできるだけ無駄のない状態に保つようにします。SetModelPropertyの代わりに使用する必要があることに注意してください。これは、プロパティ (例: ) を参照変数として laamba 関数にSetProperty渡すことができないためです。また、関連する通知プロパティが変更されたときに更新する追加のロジックが含まれていることに_dealsUser.Usernameも注意してください。IsPlannerIsPlanModerator

public class DealsUserVM : BaseViewModel
{
    private readonly IDealsUser _dealsUser;

    public DealsUserVM()
        : this(new DealsUser())
    {
        // Empty ctor
    }

    public DealsUserVM(IDealsUser dealsUser)
    {
        _dealsUser = dealsUser;
    }

    public IDealsUser Model
    {
        get
        {
            return _dealsUser;
        }
    }

    public string Username
    {
        get { return _dealsUser.Username; }
        set
        {
            SetModelProperty(_dealsUser.Username, value,
                () => { _dealsUser.Username = value; });
        }
    }

    public bool IsAdministrator
    {
        get { return _dealsUser.IsAdministrator; }
        set
        {
            SetModelProperty(_dealsUser.IsAdministrator, value,
                () => { _dealsUser.IsAdministrator = value; });
        }
    }

    public bool IsPlanModerator
    {
        get { return _dealsUser.IsPlanModerator; }
        set
        {
            // If IsPlanModerator has changed (and was updated as a result)
            if (SetModelProperty(_dealsUser.IsPlanModerator, value,
                () => { _dealsUser.IsPlanModerator = value; }))
            {
                // If IsPlanModerator is now TRUE
                if (value)
                {
                    this.IsPlanner = true;
                }
            }
        }
    }

    public bool IsPlanner
    {
        get { return _dealsUser.IsPlanner; }
        set
        {
            // If IsPlanner has changed (and was updated as a result)
            if (SetModelProperty(_dealsUser.IsPlanner, value,
                    () => { _dealsUser.IsPlanner = value; }))
            {
                // If IsPlanner is now FALSE
                if (!value)
                {
                    this.IsPlanModerator = false;
                }
            }
        }
    }

    public string EmailAddress
    {
        get { return _dealsUser.EmailAddress; }
        set
        {
            SetModelProperty(_dealsUser.EmailAddress, value,
                () => { _dealsUser.EmailAddress = value; });
        }
    }

    public override string ToString()
    {
        return _dealsUser.ToString();
    }
}

お役に立てれば :-)

于 2013-11-13T17:14:36.540 に答える