C
C#8mo ago
remi.nz

✅ Help with Data Bindings

So, now I'm trying to create a Task Manager clone, just the graphs part for now. So, I have a UserControl called Graph.xaml which is basically a graph and a text box. Then I have a Home.xaml which is my View and then HomeVM which is obviously my ViewModel. Now, I have an issue. In my Graph.xaml I've created a Binding called GraphData and then through Home.xaml I'm trying to define that GraphData so that my User Control remains re-usable and I use it for other graphs too. Home.xaml
<userControls:Graph x:Name="CPU_Graph" GraphData="{Binding GraphDataCPU}" />
<userControls:Graph x:Name="CPU_Graph" GraphData="{Binding GraphDataCPU}" />
and in my Graph.xaml, I've put it like this
<lvc:CartesianChart Series="{Binding GraphData}" LegendLocation="None" Height="250" Width="500" Hoverable="False">
<lvc:CartesianChart Series="{Binding GraphData}" LegendLocation="None" Height="250" Width="500" Hoverable="False">
but when I debug the program, it says that Graph.xaml is looking for "GraphData" in HomeVM and it's unable to find it, but instead it should look for "GraphDataCPU" as defined in Home.xaml, why is it not working?
28 Replies
remi.nz
remi.nzOP8mo ago
Graph.xaml.cs
using LiveCharts;
using System.Windows;
using System.Windows.Controls;

namespace UI_Prototype.UserControls
{
public partial class Graph : UserControl
{
public static readonly DependencyProperty GraphDataProperty =
DependencyProperty.Register("GraphData", typeof(SeriesCollection), typeof(Graph), new PropertyMetadata(null));

public SeriesCollection GraphData
{
get { return (SeriesCollection)GetValue(GraphDataProperty); }
set { SetValue(GraphDataProperty, value); }
}

public Graph()
{
InitializeComponent();
}
}
}
using LiveCharts;
using System.Windows;
using System.Windows.Controls;

namespace UI_Prototype.UserControls
{
public partial class Graph : UserControl
{
public static readonly DependencyProperty GraphDataProperty =
DependencyProperty.Register("GraphData", typeof(SeriesCollection), typeof(Graph), new PropertyMetadata(null));

public SeriesCollection GraphData
{
get { return (SeriesCollection)GetValue(GraphDataProperty); }
set { SetValue(GraphDataProperty, value); }
}

public Graph()
{
InitializeComponent();
}
}
}
Home.xaml.cs
using System.Windows.Controls;
using UI_Prototype.ViewModels;

namespace UI_Prototype.Views
{
public partial class Home : UserControl
{
public Home()
{
InitializeComponent();
DataContext = new HomeVM();
}
}
}
using System.Windows.Controls;
using UI_Prototype.ViewModels;

namespace UI_Prototype.Views
{
public partial class Home : UserControl
{
public Home()
{
InitializeComponent();
DataContext = new HomeVM();
}
}
}
It would not accept the GraphData from Home.xaml but if I put Series="{Binding GraphDataCPU}" in Graph.xaml it works and I don't want to hardcode it. Error from debugger
System.Windows.Data Error: 40 : BindingExpression path error: 'GraphData' property not found on 'object' ''HomeVM' (HashCode=5425146)'. BindingExpression:Path=GraphData; DataItem='HomeVM' (HashCode=5425146); target element is 'CartesianChart' (Name=''); target property is 'Series' (type 'SeriesCollection')
System.Windows.Data Error: 40 : BindingExpression path error: 'GraphData' property not found on 'object' ''HomeVM' (HashCode=5425146)'. BindingExpression:Path=GraphData; DataItem='HomeVM' (HashCode=5425146); target element is 'CartesianChart' (Name=''); target property is 'Series' (type 'SeriesCollection')
leowest
leowest8mo ago
you dont need to overcomplicate things the DataContext propagates to the child so if u just have <local:Graph/> in your MainWIndow.xaml for example and in your UserControl called Graph.xaml u have
<lvc:CartesianChart Series="{Binding Series}" />
<lvc:CartesianChart Series="{Binding Series}" />
and in your MainWindow vm u have a Series property it will by default reach out to it This is just an example to illustrate it:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
Series = new ISeries[]
{
new LineSeries<double>
{
Values = new double[] { 2, 1, 3, 5, 3, 4, 6 },
Fill = null
}
};
}

[ObservableProperty]
private ISeries[] _series;
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = this;
Series = new ISeries[]
{
new LineSeries<double>
{
Values = new double[] { 2, 1, 3, 5, 3, 4, 6 },
Fill = null
}
};
}

[ObservableProperty]
private ISeries[] _series;
}
XAML
<Window x:Class="RemiWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:RemiWpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<local:Graph Grid.Column="1"/>
</Grid>
</Window>
<Window x:Class="RemiWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:RemiWpf"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<local:Graph Grid.Column="1"/>
</Grid>
</Window>
Graph.xaml
<UserControl x:Class="RemiWpf.Graph"
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"
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
xmlns:local="clr-namespace:RemiWpf"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<lvc:CartesianChart Series="{Binding Series}" />
</UserControl>
<UserControl x:Class="RemiWpf.Graph"
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"
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
xmlns:local="clr-namespace:RemiWpf"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<lvc:CartesianChart Series="{Binding Series}" />
</UserControl>
leowest
leowest8mo ago
No description
remi.nz
remi.nzOP8mo ago
Yes but what if I want to re-use it, how would I change the DataBinding in that case?
leowest
leowest8mo ago
I see you want to have multiple Graphs
remi.nz
remi.nzOP8mo ago
Yes
leowest
leowest8mo ago
one way would be exposing the binding property the other would be just setting its own datacontext let me see what u did above moment
remi.nz
remi.nzOP8mo ago
alright
leowest
leowest8mo ago
<lvc:CartesianChart Series="{Binding GraphData, ElementName=self}" LegendLocation="None" Height="250" Width="500" Hoverable="False">
<lvc:CartesianChart Series="{Binding GraphData, ElementName=self}" LegendLocation="None" Height="250" Width="500" Hoverable="False">
and add to your UserControl x:Name="self"
leowest
leowest8mo ago
No description
leowest
leowest8mo ago
<local:Graph GraphData="{Binding Series}" />
<local:Graph GraphData="{Binding Series2}" Grid.Column="1"/>
<local:Graph GraphData="{Binding Series}" />
<local:Graph GraphData="{Binding Series2}" Grid.Column="1"/>
u were nearly there 😉
remi.nz
remi.nzOP8mo ago
so close yet so far wait hold on I don't understand one thing
leowest
leowest8mo ago
without self it tries to look for GraphData in the parent
remi.nz
remi.nzOP8mo ago
you said
add to your UserControl x:Name="self"
sooo
<userControls:Graph x:Name="self" GraphData="{Binding GraphDataCPU}" UsagePercentage="{Binding GraphTextInfo}"/>

<userControls:Graph x:Name="self" GraphData="{Binding GraphDataCPU}" UsagePercentage="{Binding GraphTextInfo}"/>

?
leowest
leowest8mo ago
that is not inside the graph.xaml and its not using self unless I missed something
public partial class Graph : UserControl
{
public Graph()
{
InitializeComponent();
}

public static readonly DependencyProperty GraphDataProperty =
DependencyProperty.Register("GraphData", typeof(ISeries[]), typeof(Graph), new PropertyMetadata(null));

public ISeries[] GraphData
{
get { return (ISeries[])GetValue(GraphDataProperty); }
set { SetValue(GraphDataProperty, value); }
}
}
public partial class Graph : UserControl
{
public Graph()
{
InitializeComponent();
}

public static readonly DependencyProperty GraphDataProperty =
DependencyProperty.Register("GraphData", typeof(ISeries[]), typeof(Graph), new PropertyMetadata(null));

public ISeries[] GraphData
{
get { return (ISeries[])GetValue(GraphDataProperty); }
set { SetValue(GraphDataProperty, value); }
}
}
remi.nz
remi.nzOP8mo ago
uhmm... can you please pin point me sometimes I'm just so dumb
leowest
leowest8mo ago
<UserControl x:Class="RemiWpf.Graph"
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"
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
xmlns:local="clr-namespace:RemiWpf"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" x:Name="self">
<lvc:CartesianChart Series="{Binding GraphData, ElementName=self}"/>
</UserControl>
<UserControl x:Class="RemiWpf.Graph"
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"
xmlns:lvc="clr-namespace:LiveChartsCore.SkiaSharpView.WPF;assembly=LiveChartsCore.SkiaSharpView.WPF"
xmlns:local="clr-namespace:RemiWpf"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" x:Name="self">
<lvc:CartesianChart Series="{Binding GraphData, ElementName=self}"/>
</UserControl>
remi.nz
remi.nzOP8mo ago
ahhhh ok
leowest
leowest8mo ago
like just doing x:Name means nothing if you're not using it in the scope
remi.nz
remi.nzOP8mo ago
it works but
leowest
leowest8mo ago
so if u did it on the MainWindow
remi.nz
remi.nzOP8mo ago
a lot of errors and warnings in the debugger
No description
leowest
leowest8mo ago
it wont propagate to the child
remi.nz
remi.nzOP8mo ago
No description
leowest
leowest8mo ago
I mean I dont know what else u have there... I only replied from what u provided me
remi.nz
remi.nzOP8mo ago
probably me then, I'll have a look at my code because it's a mess rn but at least I got it all figured out thanks again
leowest
leowest8mo ago
👍
MODiX
MODiX8mo ago
Use the /close command to mark a forum thread as answered
Want results from more Discord servers?
Add your server