使用Style动态更改ListBox方向

时间:2014-09-11 19:03:53

标签: silverlight windows-phone-8 listbox orientation itemspanel

我为ListBox定义了样式,以显示具有垂直或水平滚动方向的项目:

<Style x:Key="ListBoxVerticalStyle" TargetType="ListBox">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Vertical" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="ListBoxHorizontalStyle" TargetType="ListBox">
    <Setter Property="Background" Value="Transparent"/>
    <Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/>
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="Padding" Value="0"/>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <StackPanel Orientation="Horizontal" />
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
</Style>

在xaml中静态使用时,它们工作正常,例如

<ListBox Style="{StaticResource ListBoxHorizontalStyle}" ...

我正在尝试使用以下代码在C#中动态更新方向:

if (horizontal)
{
    MyListBox.Style = Resources["ListBoxHorizontalStyle"] as Style;
}
else
{
    MyListBox.Style = Resources["ListBoxVerticalStyle"] as Style;
}
MyListBox.InvalidateMeasure();
MyListBox.InvalidateArrange();

ListBox.ScrollViewer方向确实发生了变化,但项目仍保持原始方向堆叠。好像ItemsPanel更新没有得到应用。有什么我需要做的就是强制ListBox完全自我刷新吗?

2 个答案:

答案 0 :(得分:1)

当你这样做时,我不认为它会举起PropertyChange事件。在我的头脑中,我只有两个解决方案。一个是派生自己的自定义ListBox和VisualStates,这在很长时间内作为解决方案。另一个选项很简单,我们只需要通知属性已经更改,我知道如何做的最简单方法就是将它绑定到ViewModel。

为此,我将使用Page作为ViewModel,因此您的XAML就是这样


<ListBox x:Name="myListBox">
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="{Binding MYO}"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
</ListBox>

C#

using System.ComponentModel; // INotifyPropertyChanged

public partial class MainPage : PhoneApplicationPage, INotifyPropertyChanged 
{
    // implement the INotify
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    // Constructor
    public MainPage()
    {
        InitializeComponent();           
    }

    private System.Windows.Controls.Orientation _myo;
    public System.Windows.Controls.Orientation MYO
    {
        get { return _myo; }
        set { _myo = value; NotifyPropertyChanged("MYO"); }
    }

    private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
    {
        myListBox.DataContext = this;                          // have to set the datacontext to point to the page
        MYO = System.Windows.Controls.Orientation.Horizontal;  // set it to Horizontal
        // MYO = System.Windows.Controls.Orientation.Vertical; // set it to Vertical
    }
}

答案 1 :(得分:0)

点击此链接:http://msdn.microsoft.com/en-us/library/windows/apps/jj207002(v=vs.105).aspx

该教程解释了如何处理屏幕方向。