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?

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.


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"
/>

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" />

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.


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
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.