3

我为 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 完全刷新自己吗?

4

2 回答 2

1

当你这样做时,我认为它不会引发 PropertyChange 事件。在我脑海中,我只有两个解决方案。一个是派生出您自己的自定义 ListBox 和 VisualStates,作为解决方案在这里放置的时间太长了。另一个选项非常简单,我们只需要通知属性已更改,我知道如何做到这一点的最简单方法就是将其绑定到您的 ViewModel。

为此,我只是将页面用作 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
    }
}
于 2014-09-12T01:43:49.750 回答
0

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

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

于 2014-09-11T19:19:03.183 回答