Ik probeer een bar graph te maken in C# en WPF.
Mijn model:
In mijn view bind ik dit model aan een ItemsControl
Dit werkt allemaal prima, ik krijg hierdoor mooie rooie balkjes.
Nou wil ik de grafiek eigenlijk automatisch schalen in de view zodat alles mooi in beeld komt. Ik dacht, dit doe ik met een IValueConverter. Deze hoeft dan voor elk datapunt hetvolgende te doen:
Ik moet nu alleen de MaxValue en GraphHeight binden aan het model en aan de grootte van de view.
En dit lukt me niet.
Scaler toegevoegd aan de Resources van Window.
Ik moest hiervoor eerst van Scaler een subklasse van DependencyObject maken en van de 2 properties DependencyProperties zodat het binden ook werkt.
Het binden lukt niet omdat de Scaler in de Resources van het window zit en geen visual element is.
Weet iemand een manier om dit op te lossen? Of algemeen, hoe bind je een property van een visueel element aan een non-visual element in de resources?
Mijn model:
C#:
1
2
3
4
5
6
7
8
| public class Model { // bevat de datapunten public ObservableCollection<double> GraphData { get {...} } // bevat de maximale waarde in de datapunten public double MaxValue { get{...} set {...} } } |
In mijn view bind ik dit model aan een ItemsControl
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
| <ItemsControl x:Name="graph" ItemsSource="{Binding GraphData}"> <ItemsControl.ItemTemplate> <DataTemplate> <Rectangle Height="{Binding}" Fill="Red" VerticalAlignment="Bottom" /> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> |
Dit werkt allemaal prima, ik krijg hierdoor mooie rooie balkjes.
Nou wil ik de grafiek eigenlijk automatisch schalen in de view zodat alles mooi in beeld komt. Ik dacht, dit doe ik met een IValueConverter. Deze hoeft dan voor elk datapunt hetvolgende te doen:
code:
1
2
3
4
5
6
7
8
9
10
11
12
| class Scaler : IValueConverter
{
public double MaxValue { get; set; }
public double GraphHeight { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// Schaal het datapunt naar de juiste hoogte.
return ((double)value / MaxValue) * GraphHeight;
}
} |
Ik moet nu alleen de MaxValue en GraphHeight binden aan het model en aan de grootte van de view.
En dit lukt me niet.
Scaler toegevoegd aan de Resources van Window.
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| <Window ...> <Window.Resources> <local:Scaler x:Key="scaler" MaxValue={Binding MaxValue} GraphHeight={Binding ElementName=graph,Path=ActualHeight} /> </Window.Resources> <ItemsControl x:Name="graph" ItemsSource="{Binding GraphData}"> <ItemsControl.ItemTemplate> <DataTemplate> <Rectangle Height="{Binding, Converter={StaticResource scaler}}" Fill="Red" VerticalAlignment="Bottom" /> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <StackPanel Orientation="Horizontal" HorizontalAlignment="Left" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> <Window ...> |
Ik moest hiervoor eerst van Scaler een subklasse van DependencyObject maken en van de 2 properties DependencyProperties zodat het binden ook werkt.
Het binden lukt niet omdat de Scaler in de Resources van het window zit en geen visual element is.
Weet iemand een manier om dit op te lossen? Of algemeen, hoe bind je een property van een visueel element aan een non-visual element in de resources?