Problem w stylu "działa ale nie wiem dlaczego działa":)
Potrzebuje narysować pewne obrazki na podstawie dość skomplikowanych danych więc w tym celu zrobiłem sobie własną kontrolkę MyCanvas
dziedziczącą ze standardowego WPFowego Canvas
z kilkoma właściwościami, do których chcę bindować dane i na tej podstawie je wyświetlać. W celu zobrazowanie problemu trochę uprościłem zadanie do zwyczajnego rysowania prostej linii.
Kod nowej kontrolki MyCanvas
public class MyCanvas:Canvas
{
static MyCanvas()
{
var metaData = new FrameworkPropertyMetadata(new PropertyChangedCallback(OnDataChange));
metaData.AffectsRender = true;
DataDependencyProperty = DependencyProperty.Register("Coordinates", typeof(LineCoordinates), typeof(MyCanvas),metaData);
}
public static void OnDataChange(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
var canvas = d as MyCanvas;
canvas.Coordinates = e.NewValue as LineCoordinates;
canvas.Update();
}
public static readonly DependencyProperty DataDependencyProperty;
public LineCoordinates Coordinates
{
get { return GetValue(DataDependencyProperty) as LineCoordinates; }
set { SetValue(DataDependencyProperty, value); }
}
public void Update()
{
Children.Clear();
Children.Add(new Line() { X1 = Coordinates.X1, Y1 = Coordinates.Y1, X2 = Coordinates.X2, Y2 = Coordinates.Y2,Stroke=Brushes.Red,StrokeThickness=3 });
}
}
public class LineCoordinates
{
public double X1 { get; set; }
public double Y1 { get; set; }
public double X2 { get; set; }
public double Y2 { get; set; }
}
Mój view:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Row="1" Content="klik" Command="{Binding DrawLine}"/>
<local:MyCanvas Grid.Row="0" Coordinates="{Binding Line,Mode=TwoWay}"/>
</Grid>
Mój ViewModel
public class MainViewModel : ViewModelBase
{
public RelayCommand DrawLine { get; set; }
public MainViewModel()
{
DrawLine = new RelayCommand(updateLine);
Line = new LineCoordinates();
}
private void updateLine()
{
Line.X1 = 0;
Line.Y1 = 0;
Line.Y2 = 50;
Line.X2 = 50;
RaisePropertyChanged(() => Line);
}
public LineCoordinates Line { get; set; }
}
Problem jest z metodą updateLine
. Metoda w postaci przedstawionej powyżej nie działa. Tzn po kliknięciu w przycisk linia nie zostaje narysowana (tak jakby RaisePropertChanged
nie działało.
Problem ten rozwiązałem poprzez zmianę metody updateLine
na (i działa;)):
private void updateLine()
{
var line = new LineCoordinates() { X1 = 0, Y1 = 0, X2 = 50, Y2 = 50 };
Line = line;
RaisePropertyChanged(() => Line);
}
tzn tworzę nową instancję klasy LineCoordinates
i przypisuję ją do odpowiedniej właściwości ViewModelu.
Zastanawia mnie dlaczego pierwszy sposób nie działa a drugi działa (i za każdym razem muszę tworzyć nową instancję klasy do bindowania). Jakieś pomysły?
Pozdrawiam