Pergunta

Existem estruturas de dados de ligação (BCL ou não) que permitem a ligação entre o quaisquer duas propriedades CLR que implementar INotifyPropertyChanged e INotifyCollectionChanged? Parece ser, deveria ser possível fazer algo parecido com isto:

var binding = new Binding();
binding.Source = someSourceObject;
binding.SourcePath = "Customer.Name";
binding.Target = someTargetObject;
binding.TargetPath = "Client.Name";
BindingManager.Bind(binding);

Onde someSourceObject e someTargetObject são apenas POCOs que implementam INotifyPropertyChanged. No entanto, não tenho conhecimento de qualquer apoio BCL para isso, e não tenho certeza se há quadros existentes que permitem isso.

Atualizar : Dado que não há existente biblioteca disponível, eu ter tomado ele próprio sobre a escrever a minha própria. Ele está disponível aqui .

Graças

Foi útil?

Solução

Eu escrevi Truss para preencher o vazio.

Outras dicas

Eu não estou ciente de qualquer biblioteca que faz isso -. Mas você pode escrever seu próprio facilmente

Aqui está uma base Bati-se em poucos minutos, que estabelece dois dados forma vinculativa entre duas propriedades simples:

public static class Binder
{

    public static void Bind(
        INotifyPropertyChanged source,
        string sourcePropertyName,
        INotifyPropertyChanged target,
        string targetPropertyName)
    {
        var sourceProperty
            = source.GetType().GetProperty(sourcePropertyName);
        var targetProperty
            = target.GetType().GetProperty(targetPropertyName);

        source.PropertyChanged +=
            (s, a) =>
            {
                var sourceValue = sourceProperty.GetValue(source, null);
                var targetValue = targetProperty.GetValue(target, null);
                if (!Object.Equals(sourceValue, targetValue))
                {
                    targetProperty.SetValue(target, sourceValue, null);
                }
            };

        target.PropertyChanged +=
            (s, a) =>
            {
                var sourceValue = sourceProperty.GetValue(source, null);
                var targetValue = targetProperty.GetValue(target, null);
                if (!Object.Equals(sourceValue, targetValue))
                {
                    sourceProperty.SetValue(source, targetValue, null);
                }
            };
    }
}

Claro que, este código carece de algumas sutilezas. Coisas para adicionar incluem

  • Verificar se source e target são atribuídos
  • Verificar se as propriedades identificadas pelo sourcePropertyName e exist targetPropertyName
  • Verificação de compatibilidade de tipo entre as duas propriedades

Além disso, a reflexão é relativamente lento (embora de referência antes de descartá-lo, não é que lento), de modo que você pode querer usar expressões compiladas em seu lugar.

Por último, dado que especificar propriedades por corda é propenso a erros, você poderia usar expressões LINQ e os métodos de extensão em vez. Então, em vez de escrever

Binder.Bind( source, "Name", target, "Name")

Você poderia escrever

source.Bind( Name => target.Name);

AutoMapper pode copiar valores entre duas instâncias, mas você tem que escrever o seu próprio código para fazer esta acontecer automaticamente.

Bindable LINQ ou contínua linq pode ajudar aqui. Se você está tentando adicionar Propriedades modelo que são realmente do seu actual "propriedades derivadas", atualização de dados, para tornar mais fácil para você UI para vincular a, estes dois quadros devem ajudar.

Eu escrevi um pequeno Bind projeto com suporte completo para a ligação entre as propriedades neasted assíncronos acções de ligação. A sintaxe não pode ser mais simples:

//Two way binding between neasted properties:
Bind.TwoWay(()=> client.Area.Data.Name == this.AreaName);

//On change action execute:
Bind
    .OnChange(()=> client.Personal.Name)
    .Do(x => clientName = x);

Se você definiu suas propriedades como DependencyProperty 's que você poderia fazê-lo. Ambos WF e WPF tem uma implementação do mesmo (primeiro link é para WPF. Para WF é esta ), de modo que você precisa decidir qual usar -. mas ambos devem ser suficientes para suas necessidades

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