2016-03-30 1 views
0

У меня есть следующая ситуация: У меня есть сплит-просмотр из двух списков. Левый элемент-выбор вызывает правильное содержание. Если ширина окна меньше, чем 960 пикселей, я бы хотел скрыть один из списков в зависимости от выбора left-listview.Почему мой VisualStateTrigger не обновляется?

шире 960px:

| 1 | 2 |

меньше, чем 960px и SelectedIndex == -1

| 1 |

меньше 960px и SelectedIndex> = 0

| 2 |

Мой подход делает это с помощью преобразователя:

class WindowStateConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string language) 
    { 
     //Debugger.Break(); 
     if (Window.Current.Bounds.Width > 960) return 1; 
     if ((int)value == -1) return -1; 
     else return 0; 
    } 
    public object ConvertBack(object value, Type targetType, object parameter, string language) 
    { throw new NotImplementedException(); } 
} 

в моем XAML, я использую CompareStateTrigger из библиотеки WindowsStateTriggers нашел на NuGet таким образом:

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" 
     EntranceNavigationTransitionInfo.IsTargetElement="True"> 
    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup> 
      <VisualState x:Name="wideView"> 
       <VisualState.StateTriggers> 
        <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}" 
                CompareTo="1" Comparison="Equal"/> 
       </VisualState.StateTriggers> 
       <VisualState.Setters> 
        <Setter Target="ListColumn.Width" Value="360"/> 
        <Setter Target="DetailColumn.Width" Value="*"/> 
       </VisualState.Setters> 
      </VisualState> 
      <VisualState x:Name="narrowDetailView"> 
       <VisualState.StateTriggers> 
        <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}" 
                CompareTo="0" Comparison="Equal"/> 
       </VisualState.StateTriggers> 
       <VisualState.Setters> 
        <Setter Target="ListColumn.Width" Value="0"/> 
        <Setter Target="DetailColumn.Width" Value="*"/> 
       </VisualState.Setters> 
      </VisualState> 
      <VisualState x:Name="narrowListView"> 
       <VisualState.StateTriggers> 
        <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Converter={StaticResource wsc}, Mode=OneWay}" 
                CompareTo="-1" Comparison="Equal"/> 
       </VisualState.StateTriggers> 
       <VisualState.Setters> 
        <Setter Target="ListColumn.Width" Value="*"/> 
        <Setter Target="DetailColumn.Width" Value="0"/> 
       </VisualState.Setters> 
      </VisualState> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition x:Name="ListColumn" Width="0"/> 
     <ColumnDefinition x:Name="DetailColumn" Width="*"/> 
    </Grid.ColumnDefinitions> 
    <ListView x:Name="SelectionList" 
       Background="LightBlue" 
       Grid.Column="0"/> 
    <ListView x:Name="DetailsList" 
       Background="LightGreen" 
       Grid.Column="1"/> 
</Grid> 

На старт, это отлично работает, но когда я изменяю размер окна во время выполнения, ничего не происходит. Я даже разместил Debbuger.Break() внутри моего конвертера для проверки того, что он что-то делает, но это не так. У вас есть идеи для решения?

EDIT:

Я последовал описание CompositeStateTrigger, мой XAML будет выглядеть так:

<Page 
    x:Class="UWPTicketverwaltung.Views.OverviewPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:UWPTicketverwaltung.Views" 
    xmlns:triggers="using:WindowsStateTriggers" 
    xmlns:converters="using:UWPTicketverwaltung.Converters" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 
    <Page.Resources> 
     <ResourceDictionary> 
      <converters:WidthConverter x:Key="screenWidth"/> 
     </ResourceDictionary> 
    </Page.Resources> 
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" 
      EntranceNavigationTransitionInfo.IsTargetElement="True"> 
     <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup> 
       <VisualState x:Name="wideAll"> 
        <VisualState.StateTriggers> 
         <triggers:AdaptiveTrigger MinWindowHeight="960"/> 
         <!--<triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}" 
                 CompareTo="959" Comparison="GreaterThan"/>--> 
        </VisualState.StateTriggers> 
        <VisualState.Setters> 
         <Setter Target="ListColumn.Width" Value="360"/> 
         <Setter Target="DetailColumn.Width" Value="*"/> 
        </VisualState.Setters> 
       </VisualState> 
       <VisualState x:Name="narrowOverview"> 
        <VisualState.StateTriggers> 
         <triggers:CompositeStateTrigger Operator="And"> 
          <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}" 
                  CompareTo="-1" Comparison="Equal"/> 
          <triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}" 
                  CompareTo="960" Comparison="LessThan"/> 
         </triggers:CompositeStateTrigger> 
        </VisualState.StateTriggers> 
        <VisualState.Setters> 
         <Setter Target="ListColumn.Width" Value="*"/> 
         <Setter Target="DetailColumn.Width" Value="0"/> 
        </VisualState.Setters> 
       </VisualState> 
       <VisualState x:Name="narrowDetails"> 
        <VisualState.StateTriggers> 
         <triggers:CompositeStateTrigger Operator="And"> 
          <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}" 
                  CompareTo="-1" Comparison="GreaterThan"/> 
          <triggers:CompareStateTrigger Value="{x:Bind Converter={StaticResource screenWidth}, Mode=OneWay}" 
                  CompareTo="960" Comparison="LessThan"/> 
         </triggers:CompositeStateTrigger> 
        </VisualState.StateTriggers> 
        <VisualState.Setters> 
         <Setter Target="ListColumn.Width" Value="0"/> 
         <Setter Target="DetailColumn.Width" Value="*"/> 
        </VisualState.Setters> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition x:Name="ListColumn" Width="360"/> 
      <ColumnDefinition x:Name="DetailColumn" Width="*"/> 
     </Grid.ColumnDefinitions> 
     <ListView x:Name="SelectionList" 
        Background="LightBlue" 
        Grid.Column="0"/> 
     <ListView x:Name="DetailsList" 
        Background="LightGreen" 
        Grid.Column="1"/> 
    </Grid> 
</Page> 

И мой WidthConverter выглядит следующим образом:

public class WidthConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, string language) 
    { /*Debugger.Break();*/ return Window.Current.Bounds.Width; } 
    public object ConvertBack(object value, Type targetType, object parameter, string language) 
    { throw new NotImplementedException(); } 
} 

На старте все выглядит нормально , но когда я изменяю размер окна, триггер не срабатывает. Любая идея, что я делаю неправильно? Также мой конвертер запускается только один раз при запуске.

EDIT 2:

Я следовал инструкциям и Bound второй CompareStateTrigger к Grid.Width. Это мой XAML, он не использует преобразователи больше:

<Grid x:Name="MainGrid" 
     Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" 
     EntranceNavigationTransitionInfo.IsTargetElement="True"> 
    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup> 
      <VisualState x:Name="wideAll"> 
       <VisualState.StateTriggers> 
        <triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}" 
                CompareTo="959" Comparison="GreaterThan"/> 
       </VisualState.StateTriggers> 
       <VisualState.Setters> 
        <Setter Target="ListColumn.Width" Value="420"/> 
        <Setter Target="DetailColumn.Width" Value="*"/> 
       </VisualState.Setters> 
      </VisualState> 
      <VisualState x:Name="narrowOverview"> 
       <VisualState.StateTriggers> 
        <triggers:CompositeStateTrigger Operator="And"> 
         <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}" 
                 CompareTo="-1" Comparison="Equal"/> 
         <triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}" 
                 CompareTo="960" Comparison="LessThan"/> 
        </triggers:CompositeStateTrigger> 
       </VisualState.StateTriggers> 
       <VisualState.Setters> 
        <Setter Target="ListColumn.Width" Value="*"/> 
        <Setter Target="DetailColumn.Width" Value="0"/> 
       </VisualState.Setters> 
      </VisualState> 
      <VisualState x:Name="narrowDetails"> 
       <VisualState.StateTriggers> 
        <triggers:CompositeStateTrigger Operator="And"> 
         <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex, Mode=OneWay}" 
                 CompareTo="-1" Comparison="GreaterThan"/> 
         <triggers:CompareStateTrigger Value="{x:Bind MainGrid.Width, Mode=OneWay}" 
                 CompareTo="960" Comparison="LessThan"/> 
        </triggers:CompositeStateTrigger> 
       </VisualState.StateTriggers> 
       <VisualState.Setters> 
        <Setter Target="ListColumn.Width" Value="0"/> 
        <Setter Target="DetailColumn.Width" Value="*"/> 
       </VisualState.Setters> 
      </VisualState> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition x:Name="ListColumn" Width="420"/> 
     <ColumnDefinition x:Name="DetailColumn" Width="*"/> 
    </Grid.ColumnDefinitions> 
    <ListView x:Name="SelectionList" 
       Background="LightBlue" 
       Grid.Column="0"> 
     <!--<VisualStateManager.VisualStateGroups> 
      <VisualStateGroup> 
       <VisualState> 
        <VisualState.StateTriggers> 
         <triggers:CompositeStateTrigger Operator="And"> 
          <triggers:CompareStateTrigger/> 
         </triggers:CompositeStateTrigger> 
        </VisualState.StateTriggers> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups>--> 
    </ListView> 
    <ListView x:Name="DetailsList" 
       Background="LightGreen" 
       Grid.Column="1"/> 
</Grid> 

Проблема теперь в том, что, кажется, Ширина-недвижимость не будет использоваться на всех, поскольку единственным государственным Выбирается является «narrowOverview» (даже если приложение начинает шире, чем 960). Является ли способ привязки к Grid.Width неправильным?

+0

Try AdaptiveTrigger. Вот ссылка, например http://stackoverflow.com/questions/36255941/expanded-from-differen-screen-and-different-view/36256125#36256125 – Archana

+0

Кажется, вы не читали мой полный вопрос, ширина экрана не единственные критерии. –

+0

Когда вы меняете ширину, он не вызывает конвертер, потому что ширина не привязана к значению свойства. – Archana

ответ

2

Используйте CompositeStateTrigger для этого. вот link

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" x:Name="MainGrid"> 

    <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup> 
       <VisualState x:Name="wideAll"> 
        <VisualState.StateTriggers> 
         <triggers:CompositeStateTrigger Operator="And"> 
          <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}" 
                 CompareTo="-1" Comparison="GreaterThan"/> 
          <triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}" 
                CompareTo="960" Comparison="GreaterThan"/> 
         </triggers:CompositeStateTrigger> 
        </VisualState.StateTriggers> 
        <VisualState.Setters> 
         <Setter Target="ListColumn.Width" Value="420"/> 
         <Setter Target="DetailColumn.Width" Value="*"/> 
        </VisualState.Setters> 
       </VisualState> 
       <!--blue--> 
       <VisualState x:Name="narrowOverview"> 
        <VisualState.StateTriggers> 
         <triggers:CompositeStateTrigger Operator="And"> 
          <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}" 
                 CompareTo="-1" Comparison="Equal"/> 
          <triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}" 
                 CompareTo="960" Comparison="LessThan"/> 
         </triggers:CompositeStateTrigger> 
        </VisualState.StateTriggers> 
        <VisualState.Setters> 
         <Setter Target="ListColumn.Width" Value="*"/> 
         <Setter Target="DetailColumn.Width" Value="0"/> 
        </VisualState.Setters> 
       </VisualState> 
       <!--Green--> 
       <VisualState x:Name="narrowDetails"> 
        <VisualState.StateTriggers> 
         <triggers:CompositeStateTrigger Operator="And"> 
          <triggers:CompareStateTrigger Value="{x:Bind SelectionList.SelectedIndex,Mode=OneWay}" 
                 CompareTo="-1" Comparison="GreaterThan"/> 
          <triggers:CompareStateTrigger Value="{x:Bind PageViewModel.ScreenWidth,Mode=OneWay}" 
                 CompareTo="960" Comparison="LessThan"/> 
         </triggers:CompositeStateTrigger> 
        </VisualState.StateTriggers> 
        <VisualState.Setters> 
         <Setter Target="ListColumn.Width" Value="0"/> 
         <Setter Target="DetailColumn.Width" Value="*"/> 
        </VisualState.Setters> 
       </VisualState> 
      </VisualStateGroup> 
     </VisualStateManager.VisualStateGroups> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition x:Name="ListColumn" Width="420"/> 
      <ColumnDefinition x:Name="DetailColumn" Width="*"/> 
     </Grid.ColumnDefinitions> 
     <ListView x:Name="SelectionList" 
       Background="LightBlue" 
       Grid.Column="0" > 
     </ListView> 
     <ListView x:Name="DetailsList" 
       Background="LightGreen" 
       Grid.Column="1" /> 
    </Grid> 

MainPage.xaml.cs

Определить ViewModel здесь недвижимость. Назначают Vm к DataContext в конструктор

public sealed partial class MainPage : Page, INotifyPropertyChanged 
    { 
    ViewModel viewModel; 
    public ViewModel PageViewModel 
     { 
     get 
     { 
       return viewModel; 

     } 
     set 
     { 
     if(viewModel!=value) 
      { 
      viewModel= value; 
      OnPropertyChanged("PageViewModel"); 
      } 
     } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

     protected void OnPropertyChanged(string propertyName) 
     { 
      // the new Null-conditional Operators are thread-safe: 
     this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));  

     } 

public MainPage() 
{ 
           this.SizeChanged += MainPage_SizeChanged; 
           PageViewModel=(ViewModel) DataContext; 
} 

      private void MainPage_SizeChanged(object sender, SizeChangedEventArgs e) 
      { 
      PageViewModel.ScreenWidth =(int)  Window.Current.Bounds.Width; 
           Debug.WriteLine(Vm.ScreenWidth); 
      } 

      } 

Class1.CS

общественного класса ViewModel: INotifyPropertyChanged {

 int screenWidth; 
     public int ScreenWidth 
     { 
      get 
      { 
       return screenWidth; 
      } 
      set 
      { 
       if(value!=screenWidth) 
       { 
        screenWidth = value; 
        OnPropertyChanged("ScreenWidth"); 
       } 
      } 

     } 

     public event PropertyChangedEventHandler PropertyChanged; 
     protected void OnPropertyChanged(string propertyName) 
     { 
      // the new Null-conditional Operators are thread-safe: 
      this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
+1

Добро пожаловать .. Примите ответ, если он правильный :) – Archana

+0

Я сделал, но мне кажется, проблема остается прежней. См. Мой Редактировать –

+0

Есть ли проблемы при использовании AdaptiveTrigger. Вы использовали ComaprisionTrigger для ширины окон – Archana