如何在滑块位于StackPanel内时展开Slider以填充可用空间

时间:2009-12-29 18:57:46

标签: wpf slider stackpanel

Slider中插入Grid会将其展开以填充可用空间,但出于以下原因,我不希望使用网格:

我在TextBlock中有一个Slider和一个UserControl,滑块是弹簧加载并进行慢跑/穿梭;必须显示当前值,因为用户不能依赖中性光标的位置,所以文本块。实现此自定义滑块的**Orientation**属性需要旋转两个组件,并且还要调整它们的相对位置(左/右或上/下),这对于网格来说并不容易(除非我错过了某些内容)显而易见的)虽然它是StackPanel

对Aviad评论的回应

Aviad,谢谢,我为痛苦道歉;-)问题出现在标题中:当滑块位于StackPanel内时,如何扩展Slider以填充可用空间?

此用户控件:

<UserControl x:Class="XXX.Preview.SelectionView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="auto" Width="auto">
    <GroupBox Header="Selected">
        <StackPanel Orientation="Horizontal">
            <TextBlock/>
            <Slider/>
        </StackPanel>
    </GroupBox>
</UserControl>
当包含在网格中时,即使在宽度为“*”的行中,

也不会展开。滑块根本没有长度。

解决方案是在下面的代码中用网格替换堆栈面板,但我不想使用网格,因为我需要使用堆栈面板的Orientation属性来显示两个控件垂直堆叠时封闭用户控件在方向“垂直”中设置。

4 个答案:

答案 0 :(得分:5)

绑定非常简单! 请注意,StackPanel为Horizo​​ntalAlignment =“Stretch” 以及绑定所指的名称

            <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Top" Orientation="Horizontal" Name="ParentPanel">
                <Slider Minimum="1" Maximum="999999" Interval="3" Width="{Binding Path=ActualWidth, ElementName=ParentPanel}"></Slider>
            </StackPanel>

致@ somedust

按照此link进行类似的问题,了解如何使用转换器更好地控制绑定。

答案 1 :(得分:1)

您可以将Slider嵌入Grid列中,该列具有类似Witdh =&#34; *&#34;的ColumnDefinition; (即将分配可用空间)。例如,下面你可以找到如何获取TextBlock |滑块| TextBlock布局,拉伸拉伸以填充中间列中的可用空间:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>
    <TextBlock Grid.Column="0" Text="CutOff Fraction:"/>
    <Slider  Grid.Column="1"  
             x:Name="SliderCutOffFraction"
             IsEnabled="{Binding ElementName=ChkLanczosFilter, Path=IsChecked}"
             HorizontalAlignment="Stretch"
             Margin="2" 
             Minimum="0.5"
             Maximum="5" 
             SmallChange="0.25"
             LargeChange="0.5" 
             TickPlacement="BottomRight" 
             TickFrequency="0.5"
             Value="1"            
             ValueChanged="SliderCutOffFraction_OnValueChanged"/>
    <TextBlock Grid.Column="2" Width="20"
               DockPanel.Dock="Right"
               Text="{Binding ElementName=SliderCutOffFraction, Path=Value}"
               TextAlignment="Center"/>
</Grid>

答案 2 :(得分:0)

使用DockPanel而不是StackPanel可以做得更好。你可以试试。

检查一下: http://msdn.microsoft.com/en-us/library/bb628664.aspx

http://www.wpftutorial.net/DockPanel.html

答案 3 :(得分:0)

简短的回答是“你做不到”。 StackPanel受其ArrangeOverride和MeasureOverride代码的限制。它根本无法扩展以在堆叠方向上填充可用空间。

当然,您可以继承StackPanel,并以不同方式实现它,但StackPanel非常简单,如果您要这样做,您可能只是继承Panel,或者您可以继承DockPanel(具有扩展能力) ,并根据其StackPanel.Orientation属性在其所有子项上设置DockPanel.Dock:

public class StackPanelExpanding : DockPanel
{
  public Orientation Orientation
  {
    get { return (Orientation)GetValue(OrientationProperty); }
    set { SetValue(OrientationProperty, value); }
  }
  public static DependencyProperty OrientationProperty =
    StackPanel.OrientationProperty.AddOwner(typeof(StackPanelExpanding));

  protected override MeasureOverride(...)
  {
    var dock = Orientation==Orientation.Vertical ? Dock.Top : Dock.Left;
    foreach(var element in Children)
      SetDock(element, dock);
    base.MeasureOverride(...);
  }
}

您仍然没有说清楚为什么不能只使用DockPanel并在模板中使用触发器来同步Orientation和DockPanel.Dock。坦率地说,在大多数情况下,我更倾向于采用这种方式而不是创建自定义面板。