MVVM vinculação a InkCanvas
Pergunta
Eu pareço ter funcionou em um bloco de estrada. Estamos usando MVVM com Prism e ter uma visão que requer uma tela de tinta. Eu tenho criar um StrokeCollection que está sendo vinculado do meu ViewModel para a vista. Eu sou capaz de definir a coleção de minhas viewmodel mas as mudanças não estão chegando ao ViewModel enquanto o usuário desenha. Existe uma maneira de fazer este trabalho?
Meu propriedade em meu ViewModel é a seguinte:
private StrokeCollection _strokes;
public StrokeCollection Signature
{
get
{
return _strokes;
}
set
{
_strokes = value;
OnPropertyChanged("Signature");
}
}
Aqui está a minha linha de ligação XAML:
<InkCanvas x:Name="MyCanvas" Strokes="{Binding Signature, Mode=TwoWay}" />
Por alguma razão, aparentemente, os InkCanvas não notifica o ViewModel de qualquer alteração.
Solução
O problema com a sua abordagem é que você assume o InkCanvas
cria a StrokeCollection
. Não faz - ele simplesmente adiciona e remove itens a partir dele. E se a coleção não está disponível (isto é. É null
), a ligação falhará eo InkCanvas
não fará qualquer com ele. Assim:
- Você precisa criar um único
StrokeCollection
- Você precisa assumir o conteúdo da coleção vai mudar, não a coleção em si
código Exemplo:
public class ViewModel : INotifyPropertyChanged
{
private readonly StrokeCollection _strokes;
public ViewModel()
{
_strokes = new StrokeCollection();
(_strokes as INotifyCollectionChanged).CollectionChanged += delegate
{
//the strokes have changed
};
}
public event PropertyChangedEventHandler PropertyChanged;
public StrokeCollection Signature
{
get
{
return _strokes;
}
}
private void OnPropertyChanged(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
E XAML:
<InkCanvas Strokes="{Binding Signature}"/>
Outras dicas
classe StrokeCollection tem um evento chamado "StrokesChanged" que sempre é disparado quando você desenhar algo na View. Esse evento contém a coleção de traços atualizados.
XAML:
<Grid>
<InkCanvas Strokes="{Binding Signature}"/>
</Grid>
VM:
public class TestViewModel : INotifyPropertyChanged
{
public StrokeCollection Signature { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public TestViewModel()
{
Signature = new StrokeCollection();
Signature.StrokesChanged += Signature_StrokesChanged;
}
void Signature_StrokesChanged(object sender, StrokeCollectionChangedEventArgs e)
{
//PUT A BREAKPOINT HERE AND CHECK
Signature = (System.Windows.Ink.StrokeCollection)sender;
}
}
Espero que ajude!