Como você faz um controle deslizante WPF se encaixar apenas em posições inteiras discretas?

114

Freqüentemente, eu quero um controle deslizante WPF que se comporte como o System.Windows.Forms.TrackBar de antigamente. Ou seja, eu quero um controle deslizante que vai de X a Y, mas só permite que o usuário o mova em posições inteiras discretas.

Como fazer isso no WPF, já que a propriedade Value do Slider é dupla?

cplotts
fonte

Respostas:

95

Se você definir suas marcas de escala da maneira certa, poderá usar IsSnapToTickEnabled . Isso funcionou muito bem para mim. Consulte MSDN para obter detalhes.

Brian Stewart
fonte
172

A resposta simples é que você tire proveito dos IsSnapToTickEnabled e TickFrequency propriedades. Ou seja, ative o ajuste para ticks e defina a frequência de ticks para 1.

Ou, em outras palavras ... tire vantagem dos ticks ... mas você não precisa necessariamente mostrar os ticks aos quais está ajustando.

Confira a seguinte peça de xaml:

<Slider
    Orientation="Vertical"
    Height="200"
    Minimum="0"
    Maximum="10"
    Value="0"
    IsSnapToTickEnabled="True"
    TickFrequency="1"
/>
cplotts
fonte
1
Esta resposta deve ser a aceita. Funciona como um encanto. Obrigado
Ashbay
Obrigado @Ashbay ... no momento, eu queria dar crédito a outra pessoa pela resposta ... em vez de apenas marcar minha própria resposta como aceita.
cplotts
Está na seção Comum da caixa de diálogo Propriedades no designer, mas na minha máquina, pelo menos, não estava imediatamente visível porque a subseção Avançado foi recolhida e muito fácil de ignorar.
amonroejj
46

Para aqueles que desejam se ajustar a posições específicas , você também pode usar a Tickspropriedade:

<Slider Minimum="1" Maximum="500" IsSnapToTickEnabled="True" Ticks="1,100,200,350,500" />
Dave
fonte
10

O truque do snap é útil, mas tem limitações, por exemplo, se você quiser mostrar apenas um subconjunto de ticks válidos. Tive sucesso com duas alternativas: vincular a um inteiro ou arredondar o novo valor. Aqui está um exemplo combinado:

public int MyProperty { get; set; }

private void slider1_ValueChanged(object sender,
    RoutedPropertyChangedEventArgs<double> e)
{
    (sender as Slider).Value = Math.Round(e.NewValue, 0);
}

<Slider
    Name="slider1"
    TickPlacement="TopLeft"
    AutoToolTipPlacement="BottomRight"
    ValueChanged="slider1_ValueChanged"
    Value="{Binding MyProperty}"
    Minimum="0" Maximum="100" SmallChange="1" LargeChange="10"
    Ticks="0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100"/>

Não tenho ideia de como o desempenho de qualquer um se compara ao truque de encaixe, mas não tive nenhum problema *.

* Se você também vincular o valor do controle deslizante a um tipo de campo de texto, verá que, de vez em quando, se estiver usando o mouse, o campo de texto mostrará decimais. Se você também vincular a um int ao mesmo tempo, a string vazia fará com que uma exceção de conversão seja lançada, paralisando brevemente a IU. Esses problemas não foram graves o suficiente para que eu procurasse soluções.

mkjeldsen
fonte
Isso permite que o usuário também tenha os outros valores no controle deslizante? Ou ainda permite apenas que o valor dos ticks seja escolhido. Uma pergunta meio estranha ... espero que você entenda o que estou perguntando.
JLott de
1
@JLott: Você ainda pode ajustar apenas os Ticksvalores (0, 10, 20, ...) mas todos os valores intermediários (1, 2, ...) são válidos e podem ser selecionados, por exemplo, com as teclas de seta.
mkjeldsen de
Oh legal. Eu não percebi isso ... Obrigado!
JLott de
Isso funciona para Silverlight onde não há IsSnapToTickEnabledpropriedade.
ΩmegaMan