在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属性来显示两个控件垂直堆叠时封闭用户控件在方向“垂直”中设置。
答案 0 :(得分:5)
绑定非常简单! 请注意,StackPanel为HorizontalAlignment =“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可以做得更好。你可以试试。
答案 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。坦率地说,在大多数情况下,我更倾向于采用这种方式而不是创建自定义面板。