2017-09-01 1 views
0

Ich erstelle meine eigene Slider-Vorlage und Stil. Es ähnelt dem grundlegenden Schieberegler, aber die Spurleiste enthält Kreise (Ellipsen) mit einer richtigen Trennung. Die Anzahl der Kreise in der Leiste sollte so sein, dass der Schieberegler genau über ihnen hält.WPF Variable Anzahl der Elemente

In einer schnellen Annäherung sollte Slider.Maximum - Slider.Minimum/StepSize Ellipsen im Steuerelement sein. Aber meines Wissens gibt es keine Möglichkeit, eine variable Anzahl von irgendetwas von XAML anzugeben, oder?

Dies ist in der Zusammenfassung, der Code, was bedeutet ich wollen würde erreichen:

<ControlTemplate x:Key="SliderHorizontal" TargetType="{x:Type Slider}"> 
     <Grid Height="4"> 
      <Border x:Name="TrackBackground"> 
       <Rectangle x:Name="PART_SelectionRange" Fill="{StaticResource SliderThumb.Track.BackgroundSelected}" 
          HorizontalAlignment="Left" Margin="0 0 16 0" Visibility="Hidden"/> 
      </Border> 
      <Grid> 
       <!-- Have a variable ammount of column definitions and ellipses --> 
       <Grid.ColumnDefinitions> 
        <ColumnDefinition Width="4"/> 
        <ColumnDefinition Width="*"/> 
        ... 
        <ColumnDefinition Width="*"/> 
        <ColumnDefinition Width="4"/> 
       </Grid.ColumnDefinitions> 
       <Ellipse Grid.Column="0" Fill="White"/> 
       ... 
       <Ellipse Grid.Column="X" Fill="White"/> 
      </Grid> 
      <Track x:Name="PART_Track"> 
       <Track.Thumb> 
        ... 
       </Track.Thumb> 
      </Track> 
     </Grid> 
     <ControlTemplate.Triggers> 
      ... 
     </ControlTemplate.Triggers> 
    </ControlTemplate> 

Mein Code so weit erlaubt es mir, eine feste ammount von Ellipsen zu verwenden, die sehr schlecht aussieht, wenn es doesn Passen Sie nicht die Werte an, die von einem Schieberegler dargestellt werden.

Ich bin neu bei WPF, also weiß ich nicht, was dies aus Code-Behind tun würde. Kann ich einfach eine Klasse erstellen, die von Slider erbt und die Ellipsen dort hinzufügt? Wenn ja, könnte ich ein einfaches Beispiel dafür bekommen?

+1

Dies bezieht sich nicht direkt auf Ihre Frage, aber wenn Sie WPF sind, sollten Sie sich mit dem Muster MVVM einige Tutorials angeboten werden. WPF wird wesentlich einfacher damit zu arbeiten sein, und Sie werden sich später dafür bedanken, dass Sie es früh gelernt haben. –

Antwort

3

Ein ItemsControl kann eine variable Menge von etwas anzeigen. Binden Sie die Eigenschaft ItemsSource an eine Auflistung der Objekte, die Sie anzeigen möchten, und verwenden Sie die Eigenschaft ItemTemplate, um festzustellen, wie sie angezeigt werden.

Hier ist eine grobe Implementierung, die Sie fein abstimmen sollten. Insbesondere sollte TickConverterIMultiValueConverter, mit Minimum, Maximum und TickFrequency separat über eine MultiBinding gebunden sein - auf diese Weise wird automatisch wieder aufgerufen, wenn sich eine dieser Eigenschaften ändert.

public class TickConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var slider = (Slider)value; 

     var tickOffsets = new List<double>(); 

     var sliderRange = (slider.Maximum - slider.Minimum); 

     var tickcount = (int)Math.Floor(sliderRange/slider.TickFrequency); 

     return Enumerable.Range(0, tickcount); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

Vorlage:

<ControlTemplate TargetType="{x:Type Slider}" x:Key="SliderHorizontal"> 
    <ControlTemplate.Resources> 
     <local:TickConverter x:Key="TickConverter" /> 
    </ControlTemplate.Resources> 
    <Grid Height="4"> 
     <Border x:Name="TrackBackground"> 
      <Rectangle 
       x:Name="PART_SelectionRange" 
       HorizontalAlignment="Left" 
       Margin="0 0 16 0" 
       Visibility="Hidden" 
       /> 
     </Border> 
     <Grid> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition Width="*" /> 
       <ColumnDefinition Width="Auto" /> 
      </Grid.ColumnDefinitions> 
      <ItemsControl 
       Grid.Column="0" 
       ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource TickConverter}}" 
       > 
       <ItemsControl.ItemsPanel> 
        <ItemsPanelTemplate> 
         <!-- UniformGrid spaces items out evenly --> 
         <UniformGrid 
          Rows="1" 
          /> 
        </ItemsPanelTemplate> 
       </ItemsControl.ItemsPanel> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <!-- Align left to fill in start tick for each interval --> 
         <Ellipse 
          HorizontalAlignment="Left" 
          Fill="DeepSkyBlue" 
          Width="3" 
          Height="4" 
          /> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 
      <!-- And add the end tick --> 
      <Ellipse 
       Grid.Column="1" 
       HorizontalAlignment="Left" 
       Fill="DeepSkyBlue" 
       Width="3" 
       Height="4" 
       /> 
     </Grid> 
     <!-- 
     I don't know what you were doing with the thumb, but you didn't ask about it 
     so I just ignored it. 
     --> 
     <Track x:Name="PART_Track" /> 
    </Grid> 
</ControlTemplate> 
+0

In diesem Fall sollten die Ellipsen innerhalb des Schiebers eingekapselt werden, würde dies bedeuten, einen neuen Schieberegler zu erstellen? Ansonsten weiß ich nicht, wo die Sammlung definiert werden würde. – mjgalindo

+0

Sie könnten einen [Wertkonverter] (https://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter (v = vs.110) .aspx) schreiben, der eine Sammlung von Gleitkommazahlen zurückgeben würde . –

+0

@mjgalindo Siehe Aktualisierung. –

Verwandte Themen