Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[C# WPF]Binding issues graph scaling

Pagina: 1
Acties:

  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
Ik probeer een bar graph te maken in C# en WPF.

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?

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
Dit zijn van die scenario's waar naar mijn mening WPF gewoon brak werkt. Je hebt voor zover mijn ervaringen met WPF gaan (half jaartje ermee gewerkt) twee oplossingen:

1.) Gebruik een MultiValueConverter, waarbij je allebei de waardes in mee kunt geven.
2.) Verander je collection naar een IObservableCollection<Foo>, waarbij Foo een nieuwe class is die je value en max value wrapt. eventueel kun je dan zelfs de logica van een value converter verplaatsen naar een derde property op je view model.

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info


  • CM5
  • Registratie: Maart 2003
  • Niet online

CM5

Is het niet makkelijkt om je itemsControl in een viewbox te zetten, en zo te laten stretchen binnen de beschikkbare ruimte?

[ Voor 3% gewijzigd door CM5 op 16-08-2013 19:46 ]


  • epic007
  • Registratie: Februari 2004
  • Laatst online: 17-11 15:31
CM5 schreef op vrijdag 16 augustus 2013 @ 19:22:
Is het niet makkelijkt om je itemsControl in een viewbox te zetten, en zo te laten stretchen binnen de beschikkbare ruimte?
Ah cool, ik wist niet dat die bestond! Ik zat ook al ingewikkeld aan een RenderTransform te denken maar dit maakt het leven wel wat makkelijker.
Dank!