Share via

binding to a dependency property

Tom Roberts 1 Reputation point
2021-01-26T21:32:24.427+00:00

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);
        }
    }
}
Developer technologies | Windows Presentation Foundation
Developer technologies | C#
Developer technologies | C#

An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.

0 comments No comments

1 answer

Sort by: Most helpful
  1. DaisyTian-1203 11,651 Reputation points Moderator
    2021-01-27T07:29:05.257+00:00

    I tested your project, I found that you can't change the Lines value with clicking red Rectangle because you are using prism.
    I added below code to LineChart.xaml.cs

     public LineChart(int intLines)  
            {  
                Lines = intLines;  
            }  
    

    And update SetLines_MouseDown code as below:

    private void SetLines_MouseDown(object sender, MouseButtonEventArgs e)  
            {  
                if (e.Source is Rectangle)  
                {  
                    Lines = 3;  
                    LineChart myChart = new LineChart(Lines);  
                    Binding binding = new Binding("LinesProperty");  
                    binding.Source = myChart;  
                    myChart.SetBinding(LineChart.LinesProperty, binding);  
                    //BindingOperations.SetBinding(myChart, LineChart.LinesProperty, binding);  
                }  
            }  
    

    The Lines has changed but the UI didn't change, you can set a MessageBox in Set method to check it. And when you click the set button, the updating doesn't use Set Method. If I misunderstand your question,please point out. I think you can go to Prism issue to ask your question where you can be assistered better.


    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.