我已经实现了一个Windows 8 XAML VisibilitySwitchControl
,它显示了某个条件下的第一个孩子;否则显示其他控件。代码如下
[ContentProperty(Name = "Items")]
public class VisibilitySwitchControl : ItemsControl
{
public VisibilitySwitchControl()
{
DefaultStyleKey = typeof(VisibilitySwitchControl);
if (Items != null)
Items.VectorChanged += OnItemsChanged;
}
public bool ShowFirst
{
get { return (bool)GetValue(ShowFirstProperty); }
set { SetValue(ShowFirstProperty, value); }
}
public static readonly DependencyProperty ShowFirstProperty =
DependencyProperty.Register("ShowFirst", typeof(bool), typeof(VisibilitySwitchControl), new PropertyMetadata(true, OnShowFirstChanged));
public object VisibleContent
{
get { return GetValue(VisibleContentProperty); }
private set { SetValue(VisibleContentProperty, value); }
}
public static readonly DependencyProperty VisibleContentProperty =
DependencyProperty.Register("VisibleContent", typeof(object), typeof(VisibilitySwitchControl), new PropertyMetadata(null));
private static void OnShowFirstChanged(DependencyObject d, DependencyPropertyChangedEventArgs args)
{
var visibilityItemsControl = d as VisibilitySwitchControl;
if (visibilityItemsControl != null)
{
visibilityItemsControl.Evaluate();
}
}
void OnItemsChanged(IObservableVector<object> sender, IVectorChangedEventArgs evt)
{
Evaluate();
}
void Evaluate()
{
if (Items != null && Items.Any())
{
var controls = Items.OfType<FrameworkElement>().ToList();
for (var i = 0; i < controls.Count; i++)
{
if (i == 0)
{
VisibleContent = controls[i];
controls[i].Visibility = ShowFirst ? Visibility.Visible : Visibility.Collapsed;
}
else
{
controls[i].Visibility = !ShowFirst ? Visibility.Visible : Visibility.Collapsed;
}
}
}
else
{
VisibleContent = null;
}
}
}
但是,如果我在ListView
内放置两个VisibilitySwitchControl
控件,则ListView可以以大于页面的方式增长,并且不会显示滚动条。它不会停止父容器边界。
<custom:VisibilitySwitchControl ShowFirst="{Binding Path=IsFirstLevelNav}">
<ListView x:Name="FirstListView"
VerticalAlignment="Stretch"
ItemsSource="{Binding ...}"
SelectedItem="{Binding ..., Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
/>
<ListView x:Name="SecondListView"
VerticalAlignment="Stretch"
ItemsSource="{Binding ...}"
SelectedItem="{Binding ..., Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
/>
</custom:VisibilitySwitchControl>
如何强制执行孩子的VerticalAlignment="Stretch"
行为?如果我删除了我的控件并且只将一个列表直接放在代码中,那么一切都按预期工作。
感谢您的建议。
答案 0 :(得分:0)
如果您想要的是滚动一个ListView,然后当您到达最后它显示第二个ListView时,您只需要在VisibilitySwitchControl样式内的ItemPresenter周围添加ScrollViewer并禁用ListView ScrollViewer。请注意,这意味着您将丢失ListView中的虚拟化。
如果您想要的是每个ListView占用屏幕的一半而不是最简单的可能只是根据Window.Current.Bounds.Height
设置每个项目的修复高度并注册Window.Current.SizeChanged
以在窗口高度时更新它更改(确保在卸载时取消注册以防止内存泄漏)
我认为更复杂的另一种方法是将VisibilitySwitchControl的ItemsPanel更改为其他东西(默认情况下它是一个Stack面板,因此它会比屏幕大一些),比如你可以设置多个Grid将星形高度作为您拥有的项目(然后您需要设置每个项目的行)或创建自定义面板。
答案 1 :(得分:0)
您希望拉伸列表视图的高度,尝试将其绑定到父级的实际高度
下面是您需要包含的代码部分
Height="{Binding ActualHeight, ElementName=parentContainer}"
其中parentContainer
是您正在使用的custom:VisibilitySwitchControl
的名称。这会将高度绑定到父容器的显示高度。试试让我知道