Pergunta

Aqui está um exemplo básico para explicar meu problema. Digamos que eu tenho

ObservableCollection<int> Numbers {get; set;}

e um IValueConverter que retorna a soma dos números.

Normalmente, o que eu faria é mudar o IVALUECONVERTER em um imultivalueConverter e vincular um segundo valor a números.

<MultiBinding Converter="{StaticResource SumTheIntegersConverter}">
    <Binding Path="Numbers"     />
    <Binding Path="Numbers.Count"   />
</MultiBinding>

No entanto, não consigo usar esse método para resolver meu problema real. Parece que deve haver uma maneira melhor de atualizar a ligação quando a coleção muda em que eu simplesmente não estou pensando. Qual é a melhor maneira de executar o conversor de valor quando os itens são adicionados e removidos aos números?

Foi útil?

Solução

Acabei fazendo algo assim que parece funcionar. Está longe de ser uma solução ideal e eu ainda estaria interessado em algo melhor, mas parece funcionar para meus propósitos.

class CollectionChangedHandlingValueConverter : IValueConverter
{
    DependencyObject myTarget;
    DependencyProperty myTargetProperty;

    //If this ever needs to be called from XAML you can make it a MarkupExtension and use ProvideValue to set up the Target and TargetProperty
    public CollectionChangedHandlingValueConverter(DependencyObject target, DependencyProperty dp)
    {
        myTarget = target;
        myTargetProperty = dp;
    }

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        INotifyCollectionChanged collection = value as INotifyCollectionChanged;
        if (collection != null)
        {
            //It notifies of collection changed, try again when it changes
            collection.CollectionChanged += DataCollectionChanged;
        }

        //Do whatever conversions here
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion

    void DataCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if ((myTarget != null) && (myTargetProperty != null))
        {
            BindingOperations.GetBindingExpressionBase(myTarget, myTargetProperty).UpdateTarget();
        }
    }
}

Outras dicas

Isso é realmente surpreendentemente muito difícil. Um IVALUECONVERTER não atualiza, então isso não funciona como você espera.

Eu escrevi uma amostra na galeria da Microsoft Expression chamada Agregador de coleções Isso mostra uma abordagem de funcionamento, se complicada, para fazer esse trabalho através de um comportamento que faz a agregação (contagem, no seu caso, embora eu também apóie a soma, a média etc.) para você, em vez de um conversor.

E acabei sincronizando a coleção (original com conversor), dê uma olhada no Buttom da minha postagem, por exemplo:

http://alexburtsev.wordpress.com/2011/03/05/mvvm-pattern-in-silverlight-and-wpf/

Em seu modelo, inscreva -se na Coleção e levante a PropertyChanged:

Numbers.CollectionChanged += (o,e) => 
  OnPropertyChanged(new PropertyChangedEventArgs(nameof(Numbers)));
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top