My solution has two projects: one is called ChartControl and the other is LineGridViewCh4. LineGridViewCh4 contains the view and viewmodel that uses the control ChartControl. I can change the property Lines and the view gets updated and updates the Lines dependency property and Lines property in ChartStyle.cs. This is working fine. What I want to make happen is communication in the other direction. For example. If the Lines property were to change (by mousedown in the red square to set the Lines property to 3) in ChartStyle.cs, I'd like to have the property Lines (in ChartStyle.cs) update the dependency property in LineChart.xaml.cs and the change reflected in the view LineGridControlView.xaml. I tried creating a binding statement in the ctor of LineChart.xaml.cs but I'm not sure how to do this or if this is the right approach. In LineChart.xaml.cs method SetLineChart() has a statement cs.Line = Line; and can only work in one direction. It seems like I need Line = cs.Line; somewhere for the reverse direction. Any help would be appreciated.
ChartStyle.cs
using Prism.Mvvm;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Shapes;
namespace ChartControl.ChartModel
{
public class ChartStyle : BindableBase
{
public Canvas ChartCanvas { get; set; }
public double Lines { get; set; }
public void AddChartStyle()
{
for (int i = 1; i <= Lines; i++)
{
double dx = i * 10;
Line gridline = new Line();
gridline.Stroke = Brushes.Black;
gridline.StrokeThickness = 4;
gridline.X1 = new Point(dx, 0).X;
gridline.Y1 = new Point(dx, 0).Y;
gridline.X2 = new Point(dx, 100).X;
gridline.Y2 = new Point(dx, 100).Y;
ChartCanvas.Children.Add(gridline);
}
Rectangle setLines = new Rectangle
{
Fill = Brushes.Red,
StrokeThickness = 2
};
setLines.Width = 30;
setLines.Height = 30;
Canvas.SetTop(setLines, 110);
ChartCanvas.Children.Add(setLines);
setLines.MouseDown += new MouseButtonEventHandler(SetLines_MouseDown);
}
private void SetLines_MouseDown(object sender, MouseButtonEventArgs e)
{
if (e.Source is Rectangle)
{
Lines = 3;
}
}
}
}
LineChart.xaml
<UserControl x:Class="ChartControl.Views.LineChart"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True">
<Grid >
<Canvas Name="chartCanvas"/>
</Grid>
</UserControl>
LineChart.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;
using ChartControl.ChartModel;
namespace ChartControl.Views
{
public partial class LineChart : UserControl
{
private ChartStyle cs;
public LineChart()
{
InitializeComponent();
cs = new ChartStyle();
cs.ChartCanvas = chartCanvas;
//Binding csLine = new Binding("Lines");
//csLine.Source = cs.Lines;
//Lines.SetBinding(LinesProperty, csLine);
}
protected override void OnRender(DrawingContext drawingContext)
{
SetLineChart();
}
private void SetLineChart()
{
cs.Lines = Lines;
RedrawLineChart();
}
private void RedrawLineChart()
{
chartCanvas.Children.Clear();
cs.AddChartStyle();
}
public static DependencyProperty LinesProperty =
DependencyProperty.Register("Lines", typeof(int),
typeof(LineChart),
new FrameworkPropertyMetadata(12, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault |
FrameworkPropertyMetadataOptions.AffectsRender));
public int Lines
{
get { return (int)GetValue(LinesProperty); }
set { SetValue(LinesProperty, value); }
}
}
}
LineGridControlView.xaml
<Window x:Class="LineGridViewCh4.Views.LineGridControlView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
xmlns:local="clr-namespace:ChartControl.Views;assembly=ChartControl"
prism:ViewModelLocator.AutoWireViewModel="True"
Height="220" Width="400">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Grid.Column="1" Margin="5">
<StackPanel Orientation="Horizontal">
<Label Content="Lines" Width="60" Height="25"/>
<TextBox x:Name="tbLines" Width="50" Height="25" Text="{Binding Lines, ElementName=myChart}"/>
<Button Content="Set" Command="{Binding ChangeLinesCommand}" CommandParameter="{Binding Text, ElementName=tbLines}"/>
</StackPanel>
</StackPanel>
<local:LineChart x:Name="myChart" Margin="10"/>
</Grid>
</Window>
LineGridControlViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using System;
namespace LineGridViewCh4.ViewModels
{
public class LineGridControlViewModel : BindableBase
{
public DelegateCommand<string> ChangeLinesCommand { get; set; }
public LineGridControlViewModel()
{
ChangeLinesCommand = new DelegateCommand<string>(ChangeLines);
}
private int lines;
public int Lines
{
get { return lines; }
set { SetProperty(ref lines, value); }
}
public void ChangeLines(string numberOfLines)
{
Lines = Convert.ToInt32(numberOfLines);
}
}
}