Динамически изменить ориентацию ListBox с помощью стиля

Я определил стили для 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 ответа

Решение

Я не думаю, что это вызывает событие 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
    }
}

Проверьте эту ссылку: http://msdn.microsoft.com/en-us/library/windows/apps/jj207002(v=vs.105).aspx

Этот урок объясняет, как управлять ориентацией экрана.

Другие вопросы по тегам