Pergunta

Ao implementar o ViewModel em um aplicativo de arquitetura WPF Model-View-ViewModel parece haver duas opções principais como fazê-lo databindable. Eu vi implementações que o uso DependencyProperty para propriedades a vista é indo para vincular contra e eu vi o ViewModel implementação INotifyPropertyChanged vez.

A minha pergunta é quando eu deve preferir um sobre o outro? Há alguma diferença de desempenho? É realmente uma boa idéia para dar as dependências ViewModel para WPF? O que mais eu preciso para considerar quando tomar a decisão de design?

Foi útil?

Solução

Kent escreveu um blog interessante sobre este tópico: Ver modelos: POCOs contra DependencyObjects .

Breve resumo:

  1. DependencyObjects não são marcadas como serializable
  2. Substitui o DependencyObject classe e sela a equals () e GetHashCode () métodos
  3. A DependencyObject tem afinidade de segmento - que só pode ser acessado no segmento em que foi criado

Eu prefiro a abordagem POCO. A classe base para PresentationModel (aka ViewModel) que implementa INotifyPropertyChanged interface pode ser encontrada aqui: http://compositeextensions.codeplex.com

Outras dicas

De acordo com o guia de desempenho WPF, DependencyObjects definitivamente melhor desempenho do que POCOs que implementam INotifyPropertyChanged:

http://msdn.microsoft.com/en-us/library/ bb613546.aspx

A escolha é totalmente baseado em sua lógica de negócios e nível de abstração UI. Se você não quer uma boa separação, em seguida DP irá trabalhar para você.

DependencyProperties será aplicável principalmente ao nível VisualElements por isso não vai ser boa idéia se nós criamos monte de PD para cada um dos nossos requisitos de negócios. Também há um custo maior para o DP de um INotifyPropertyChanged. Quando você cria um WPF / Silverlight tentar projetar UI e ViewModel totalmente separado para que, em qualquer ponto do tempo nós podemos mudar os controles de layout e UI (Baseado no tema e Styles)

Consulte este post também - https: // stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel. O link tem um monte de referência a padrão Model-View-ViewModel, que é muito relevante para esta discussão.

Do ponto de vista expressividade, eu desfrutar completamente usando propriedades de dependência e assustar com o pensamento de INotifyPropertyChanged. Além dos nomes de propriedade string e possíveis vazamentos de memória devido à inscrição de evento, INotifyPropertyChanged é um mecanismo muito mais explícito.

As propriedades de dependência implica "quando isso, faça aquilo" usando facilmente compreensível metadados estático. É uma abordagem declarativa que tem o meu voto para a elegância.

INotifyPropertyChanged quando usado também lhe dá a capacidade de adicionar mais lógica no código de seus getters e setter de suas propriedades.

exemplo DependencyProperty:

public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );

public String Name
{
    set { SetValue( NameProperty, value ); }
    get { return ( String ) GetValue( NameProperty ); }
}

Em seu getter e setter --- tudo o que você pode fazer é simplesmente chamar SetValue e GetValue respectivamente, b / c em outras partes do quadro do getter / setter não é chamado, em vez disso, directamente chama SetValue, GetValue, para que o seu wouldnt lógica propriedade confiável ser executado.

Com INotifyPropertyChanged, definir um evento:

public event PropertyChangedEventHandler PropertyChanged;

E então simplesmente ter qualquer lugar lógica no seu código, em seguida, chamar:

// ...
// Something cool...
// ...

if( this.PropertyChanged != null )
{
    PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}

// More cool stuff that will reliably happen...

Esta poderia ser em um getter / setter, ou em qualquer outro lugar.

As propriedades de dependência são destinados a suportes de ligação (como um alvo) em elementos de interface do usuário não como uma fonte de ligação de dados, este é o lugar onde INotifyProperty entra. De um ponto de vista puramente você não deve usar DP em um ViewModels.

"Para ser a fonte de uma ligação, uma propriedade não precisa ser um propriedade de dependência, você pode usar qualquer propriedade CLR como uma fonte de ligação No entanto, a fim de ser o alvo de uma ligação, a propriedade. deve ser uma propriedade de dependência. para um one-way ou de ligação para ser eficaz nos dois sentidos, a propriedade de origem deve suportar notificações de alteração que se propagam para o sistema de ligação e assim o alvo. para CLR personalizado fontes de ligação, isto significa que a propriedade deve apoiar INotifyPropertyChanged. coleções devem apoiar INotifyCollectionChanged ".

Todos os objetos de dependência não pode ser serializado (Isso pode dificultar a utilização dos ViewModels e DTO (POCO) 's.

Existem diferenças entre DP dentro Silverlight comparação com WPF.

http://msdn.microsoft.com /en-us/library/cc221408(v=VS.95).aspx

http://msdn.microsoft.com/en -us / library / cc903933 (VS.95) .aspx

Eu também teve de considerar esta decisão recentemente.

Eu achei que o mecanismo de INotifyPropertyChanged adequados meu necessidades melhor porque permitiu-me para colar minha GUI para um quadro lógica de negócios existente sem duplicar estado. O quadro que eu estava usando tinha o seu próprio padrão de observador e era fácil de transmitir a um nível de notificação para a próxima. Eu simplesmente tinha uma classe que implementou a interface observador da minha estrutura lógica de negócios ea interface INotifyPropertyChanged.

Com DP você não pode definir o backend que armazena o estado sozinho. Eu teria que deixar .net cache de uma cópia de cada item de estado eu estava ligado. Esta parecia ser uma sobrecarga desnecessária -. Meu estado é grande e complicado

Então aqui eu encontrei INotifyPropertyChanged melhor para expor propriedades de lógica de negócios para GUI.

Dito onde eu precisava de uma GUI costume widget para expor uma propriedade e para que as alterações que a propriedade de afetar outro GUI widgets da DP provou a solução simples.

Assim lá eu encontrei DP útil para GUI para notificação GUI.

É realmente uma boa idéia para dar as dependências ViewModel para WPF?

.NET 4.0 terá System.Xaml.dll, assim você não terá que tomar uma dependência em um quadro arbitrário para utilizá-lo. Veja pós de Rob Relyea sobre sua sessão de PDC.

Minha opinião

XAML é uma linguagem para descrever objetos e WPF é uma estrutura cujos objetos descritos são elementos de interface do usuário.

Seu relacionamento é semelhante ao C #, uma linguagem para descrever a lógica, e .NET, um quadro que implementa determinados tipos de lógica.

O propósito de XAML é gráficos de objetos declarativas. As tecnologias W * F são grandes candidatos para este paradigma, mas XAML existe independentemente deles.

XAML e todo o sistema de dependências foram implementadas como pilhas separadas para WF e WPF, provavelmente para alavancar a experiência de diferentes equipes sem criar uma dependência (sem trocadilhos) entre eles.

propriedades

dependência são a cola de criação de controle personalizado. Se você está interessado em usar o Intelli-sentido para mostrar suas propriedades na janela de propriedades em tempo de design XAML você deve usar propriedades de dependência. INPC nunca vai mostrar uma propriedade na janela de propriedade em tempo de design.

Parece que propriedades de dependência deve ser usado em controles que você cria, tal como botões. Para usar propriedades em XAML e usar todos os WPF apresenta, essas propriedades devem propriedades de dependência.

No entanto, o seu ViewModel é melhor fora de usar INotifyPropertyChanged. Usando INotifyPropertyChanged lhe dará a capacidade de ter lógica getter / setter se você precisa.

Eu recomendo verificar a versão de Josh Smith de uma classe base para um ViewModel que já implementa INotifyPropertyChanged:

http: // joshsmithonwpf. wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/

Eu penso que este é um excelente exemplo de como fazer um ViewModel.

Eu acho que DependencyProperty e INotifyPropertyChanged são usados ??para duas coisas diferentes em Encadernação: o primeiro para permitir uma propriedade a ser alvo de uma ligação e receber a entrada de outro imóvel (use {Binding ...} para definir a propriedade) , a última quando você deseja que o valor de uma propriedade para ser utilizado como a fonte de uma ligação (nome no Expression caminho de ligação). Assim, a escolha é meramente técnica.

Eu prefiro uma abordagem mais direta, o que eu escrevi sobre no Apresentação Modelo Sem INotifyPropertyChanged . Usando uma alternativa para a ligação de dados, pode ligar-se directamente às propriedades CLR sem qualquer código de contabilidade. Você acabou de escrever um código simples de idade .NET em sua Model View, e ele é atualizado quando o seu modelo de dados muda.

Há apenas uma coisa por que preferem um DependencyObject - A ligação vai funcionar melhor. Basta tentar um exemplo com um ListBox e TextBox, lista preenchidos com dados de propriedade INotifyPropertyChanged vs. DependencyProperty e item atual edição de TextBox ...

Se você quiser expor propriedades para outros controles que você deve usar propriedades de dependência ... mas boa sorte, porque eles demoram um pouco para descobrir ...

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top