在运行时隐藏和显示数据绑定PivotItem头

时间:2012-05-25 18:45:20

标签: wpf xaml data-binding windows-phone-7.1

我认为PivotItem的当前实现有点不一致,不能说是有缺陷的。如果在完全呈现之前或之后设置属性Header,则会正确设置标头的大小,但是,将Header设置回null或string.empty不会导致标头再次收缩。当通过DataBinding设置Header时,是否有一种隐藏和显示PivotItem头的优雅方式,或者是否可以强制PivotItem重新验证它的边界?

截至目前,我正在尝试用一些相当粗糙的代码“解决”我的问题,其中包括事件和以编程方式完全重新创建Pivot,然后再次附加所有PivotItem。也许只是页面的一个好的解决方案,但当需要完成10次以上时,肯定有些不确定。

[before已向somewhat similiar context提出了这个问题,但从未真正解决过。{/ p>

4 个答案:

答案 0 :(得分:1)

您是否尝试在保留其他标头的同时仅移除一个项目的标头?如果是这样,我不会推荐这个。这会很混乱。

如果尝试折叠所有这些,您可以将PivotHeaderTemplate的可见性绑定到一些东西。一个是页面的DataContext

<controls:Pivot x:Name="MyPivot" >
    <controls:Pivot.HeaderTemplate>
        <DataTemplate>
            <Grid Visibility="{Binding DataContext.HeaderVisibility, ElementName=MyPivot}">
            <TextBlock Text="{Binding}" FontSize="{StaticResource PhoneFontSizeExtraExtraLarge}" />
            </Grid>
        </DataTemplate>
    </controls:Pivot.HeaderTemplate>

然后,您可以在页面的viewmodel中拥有HeaderVisibility属性。

如果要将标题的文本设置为null,则可以使用值转换器

XAML:

<controls:Pivot x:Name="MyPivot" >
    <controls:Pivot.HeaderTemplate>
        <DataTemplate>
            <Grid Visibility="{Binding Converter={StaticResource TextToVisibilityConverter}}">
            <TextBlock Text="{Binding}" FontSize="{StaticResource PhoneFontSizeExtraExtraLarge}"/>
            </Grid>
        </DataTemplate>
    </controls:Pivot.HeaderTemplate>

转换器:

public class TextToVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) return Visibility.Collapsed;

        return (string.InNullOrEmpty(value.ToString()) ? Visibility.Collapsed : Visibility.Visible;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

答案 1 :(得分:0)

您是否尝试过将pivot的标题高度绑定到更新的属性,因为标题文本设置为空/ null(值为0?)

如果可行,也许你可以尝试的另一件事是将Height属性绑定到与标题文本相同的值,以及转换器(伪:如果text为null,则返回0表示高度) - 这样你就不会有一个额外的财产值得担心。

答案 2 :(得分:0)

我发现更改Visiblity或减少PivotItem的标题高度对于已经渲染的项目不起作用(但是?)。它只是被打破了,但是可以通过移动PivotItem的第一个子元素,通过将其上边距更改为负值来绕过这些缺点。不可否认,不是优雅,而是工作。这是一些代码:

<phone:PhoneApplicationPage.Resources>
    <local:SubtitleConverter x:Key="SubtitleConverter" />
    <local:MarginConverter x:Key="MarginConverter" />       
</phone:PhoneApplicationPage.Resources>

<controls:PivotItem Name="LayoutItem" Header="{Binding Path=MyProgramSettings.ShowHeader, Converter={StaticResource SubtitleConverter}}">
    <ListBox Margin="{Binding Path=MyProgramSettings.ShowHeader, Converter={StaticResource MarginConverter}}"> 
        <!-- element that is moved up and down depending on some property -->
    </ListBox>
</controls:PivotItem>

背后的代码

public class SubtitleConverter : ConverterBase
    {
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {   
            /* should always return a non empty string, making the PivotItem header height predictable */
            /* needed for MarginConverter */
            return MyProgramSettings.ShowHeader ? " " : MyResource.SomeText.ToLower();
        }
    }

    public class MarginConverter : ConverterBase
    {
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool && (bool)value)
            {
                return new Thickness(12, 0, -28, 0);
            }
            return new Thickness(12, 0, -12, 0);
        }
    }

答案 3 :(得分:0)

好主意! 我没有准确地使用你的解决方案,但我的灵感来自你的想法。

这是我做的:

1.将StackPanel创建为容器,将上边距设置为负值,例如Margin="0,-35,0,0"

2.添加一些TextBlock来伪造Pviot Headers,设置你想要与Headers绑定的数据绑定。

3.设置TextBlocks Width = "Auto",添加一些右边距,这样就不会太拥挤

注意:当第一个TextBlock代表当前的PivotItem时,其他的代表其他的 - 它们处于激活状态。

4.对于未激活的PivotItems的TextBlocks,我们设置Foreground="#FF727272"以区分激活的PivotItems。并且还添加一个事件处理程序,例如Tap="GoToPivot2_Tap"后面有简单的代码:PivotRoot.SelectedItem = Pivot2;

<controls:Pivot x:Name="PivotRoot">

    <controls:PivotItem x:Name="Pivot1">
        <StackPanel Margin="0,-35,0,0" Orientation="Horizontal">
            <TextBlock Text="{Binding Header1}" Width="Auto" Margin="0,0,25,0" FontSize="30"/>
            <TextBlock Text="{Binding Header2}" Tap="GoToPivot2_Tap" Width="Auto" Margin="0,0,25,0" Foreground="#FF727272" FontSize="30"/>
            <TextBlock Text="{Binding Header3}" Tap="GoToPivot3_Tap" Width="Auto" Margin="0,0,25,0" Foreground="#FF727272" FontSize="30"/>
        </StackPanel>
    </controls:PivotItem>

    <controls:PivotItem x:Name="Pivot2">
        <StackPanel Margin="0,-35,0,0" Orientation="Horizontal">
            <TextBlock Text="{Binding Header2}" Width="Auto" Margin="0,0,25,0" FontSize="30"/>
            <TextBlock Text="{Binding Header3}" Tap="GoToPivot3_Tap" Width="Auto" Margin="0,0,25,0" Foreground="#FF727272" FontSize="30"/>
            <TextBlock Text="{Binding Header1}" Tap="GoToPivot1_Tap" Width="Auto" Margin="0,0,25,0" Foreground="#FF727272" FontSize="30"/>
        </StackPanel>
    </controls:PivotItem>

    <controls:PivotItem x:Name="Pivot3">
        <StackPanel Margin="0,-35,0,0" Orientation="Horizontal">
            <TextBlock Text="{Binding Header3}" Width="Auto" Margin="0,0,25,0" FontSize="30"/>
            <TextBlock Text="{Binding Header1}" Tap="GoToPivot1_Tap" Width="Auto" Margin="0,0,25,0" Foreground="#FF727272" FontSize="30"/>
            <TextBlock Text="{Binding Header2}" Tap="GoToPivot2_Tap" Width="Auto" Margin="0,0,25,0" Foreground="#FF727272" FontSize="30"/>
        </StackPanel>
    </controls:PivotItem>
</controls:Pivot>

就是这样。

也许事件不如你的优雅,但也有效。