VisualStateManager не скрывает элемент управления в UWP, когда ширина становится небольшой
Я использовал VisualStateManager, чтобы скрыть (свернуть) элемент управления изображением в приложении UWP, поэтому я знаю, что он работает. Но в этом одном примере (ниже) это не так. Я не могу понять, почему большое изображение (называемое imgCarDetail) не исчезает и не появляется снова, когда я растягиваю страницу все шире и уже. Я думаю, что это может быть связано с привязкой данных, но я не понимаю, почему это повлияет на это.
Любые предложения приветствуются.
MainPage.xaml
<Page
x:Class="StackruExample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:StackruExample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:data="using:StackruExample.Classes"
SizeChanged="Page_SizeChanged"
Loaded="Page_Loaded"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<!-- Adjust controls on the page based on the size of the screen -->
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="vsSmallPhone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="10" />
</VisualState.StateTriggers>
<VisualState.Setters>
<!--<Setter Target="lblManufacturerName.FontSize" Value="12" />-->
<Setter Target="imgCarDetail.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="vsPhone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="500" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="lblManufacturerName.FontSize" Value="18" />
<Setter Target="imgCarDetail.Visibility" Value="Collapsed" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="vsTablet">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="lblManufacturerName.FontSize" Value="24" />
<Setter Target="imgCarDetail.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="vsDesktop">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1024" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="lblManufacturerName.FontSize" Value="32" />
<Setter Target="imgCarDetail.Visibility" Value="Visible" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Name="tblPage" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="30" x:Name="RowOne" />
<RowDefinition Height="*" x:Name="RowTwo" />
<RowDefinition Height="165" x:Name="RowThree" />
<RowDefinition Height="308" x:Name="RowFour" />
</Grid.RowDefinitions>
<TextBlock Name="LabelPageSize" Text="size_here" Grid.Row="0" Margin="5" />
<!-- List of all of the car makers -->
<ScrollViewer VerticalScrollBarVisibility="Visible" Grid.Row="1">
<ListView Name="lvwMaster" ItemsSource="{x:Bind colAllCarMakers}" IsItemClickEnabled="True" ItemClick="lvwMaster_ItemClick">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:Manufacturer">
<TextBlock Name="lblManufacturerName" FontSize="32" Text="{x:Bind Name}" TextWrapping="Wrap" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
<!-- List of the cars built by the selected car maker -->
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Hidden" Grid.Row="2">
<GridView Name="grdAllCars" ItemsSource="{x:Bind colAllCars}" IsItemClickEnabled="True" ItemClick="grdAllCars_ItemClick" Margin="5,5,5,10" >
<GridView.ItemTemplate>
<DataTemplate x:DataType="data:Car">
<Image Name="imgCarThumbnail" Source="{x:Bind CarImage}" Width="100" Height="149"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</ScrollViewer>
<!-- Car details for a selected Car -->
<Grid Grid.Row="3" HorizontalAlignment="Left" VerticalAlignment="Top" Name="tblCarDetails" Margin="5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Name="imgCarDetail" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Top" Width="200" Height="298"/>
<TextBlock Name="lblCarDetailID" TextWrapping="Wrap" Grid.Row="0" Grid.Column="1" Margin="10,0,10,0" Text="car_id"/>
<TextBlock Name="lblCarDetailName" FontSize="32" Grid.Row="1" Grid.Column="1" Margin="10,0,10,10" Text="Car name" TextWrapping="Wrap"/>
</Grid>
</Grid>
</Grid>
MainPage.xaml.cs
using StackruExample.Classes;
using System;
using System.Collections.ObjectModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;
namespace StackruExample {
public sealed partial class MainPage : Page
{
public ObservableCollection<Manufacturer> colAllCarMakers { get; set; }
public ObservableCollection<Car> colAllCars { get; set; }
public MainPage()
{
this.InitializeComponent();
colAllCarMakers = new ObservableCollection<Manufacturer>();
colAllCars = new ObservableCollection<Car>();
}
private void Page_SizeChanged(object sender, SizeChangedEventArgs e) {
LabelPageSize.Text = "W/H: " + this.ActualWidth.ToString() + "/" + this.ActualHeight.ToString();
}
private async void Page_Loaded(object sender, RoutedEventArgs e) {
await CarManager.GetManufacturers(colAllCarMakers);
lvwMaster.SelectedIndex = 0;
Manufacturer xSelectedManufacturer = (Manufacturer)lvwMaster.SelectedItem;
DisplayAllCarsForTheSelectedManufacturer(xSelectedManufacturer);
SelectFirstCarInList();
}
private void lvwMaster_ItemClick(object sender, ItemClickEventArgs e) {
Manufacturer xSelectedManufacturer = (Manufacturer)e.ClickedItem;
DisplayAllCarsForTheSelectedManufacturer(xSelectedManufacturer);
SelectFirstCarInList();
}
private void grdAllCars_ItemClick(object sender, ItemClickEventArgs e) {
Car xSelectedCar = (Car)e.ClickedItem;
DisplayDetailsAboutTheSelectedCar(xSelectedCar);
}
/// <summary>
/// Use this function to select a Car in the list, and then display the details about the Car.
/// </summary>
public void SelectFirstCarInList() {
try {
grdAllCars.SelectedIndex = 0;
Car xSelectedCar = (Car)grdAllCars.SelectedItem;
DisplayDetailsAboutTheSelectedCar(xSelectedCar);
} catch (Exception) {
//
}
}
/// <summary>
/// Use this function to display all of the Cars in a particular Manufacturer.
/// </summary>
/// <param name="xSelectedManufacturer">The Manufacturer that you want to display all of the Cars in that Manufacturer.</param>
public void DisplayAllCarsForTheSelectedManufacturer(Manufacturer xSelectedManufacturer) {
try {
colAllCars.Clear();
foreach (Car xOneCar in xSelectedManufacturer.Cars) {
colAllCars.Add(xOneCar);
}
} catch (Exception) {
//
}
}
/// <summary>
/// Use this function to display additional details about a Car that was selected from the list.
/// </summary>
/// <param name="xSelectedCar">The Car that you want to display additional details about in the lower pane of the page.</param>
public void DisplayDetailsAboutTheSelectedCar(Car xSelectedCar) {
try {
// Display what we know about the selected Car
imgCarDetail.Source = new BitmapImage(new Uri("ms-appx:///" + xSelectedCar.CarImage));
lblCarDetailID.Text = xSelectedCar.CarID + "";
lblCarDetailName.Text = xSelectedCar.Model;
} catch (Exception) {
//
}
}
}
}
Это может показаться большим количеством кода, но я хочу дать вам все необходимое для запуска и тестирования приложения, так что вот дополнительный код, который вам понадобится для его работы.
Car.cs
namespace StackruExample.Classes {
public class Car {
public int CarID { get; set; }
public string Model { get; set; }
public string CarImage {
get { return string.Format("Assets/Cars/{0}.jpg", CarID); }
}
}
}
Manufacturer.cs
using System.Collections.Generic;
namespace StackruExample.Classes {
public class Manufacturer {
public int ManufacturerID { get; set; }
public string Name { get; set; }
public List<Car> Cars { get; set; }
public Manufacturer() {
this.Cars = new List<Car>();
}
}
}
CarManager.cs
using System;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
namespace StackruExample.Classes {
public class CarManager {
public static async Task GetManufacturers(ObservableCollection<Manufacturer> colCarMakers) {
try {
Manufacturer makerAudi = new Manufacturer { ManufacturerID = 10, Name = "Audi" };
makerAudi.Cars.Add(new Car { CarID = 111, Model = "A3" });
makerAudi.Cars.Add(new Car { CarID = 112, Model = "A4" });
makerAudi.Cars.Add(new Car { CarID = 113, Model = "A5" });
Manufacturer makerFord = new Manufacturer { ManufacturerID = 11, Name = "Ford" };
makerFord.Cars.Add(new Car { CarID = 114, Model = "Focus" });
makerFord.Cars.Add(new Car { CarID = 115, Model = "Mustang" });
makerFord.Cars.Add(new Car { CarID = 116, Model = "Bronco" });
Manufacturer makerVW = new Manufacturer { ManufacturerID = 12, Name = "Volkswagen" };
makerVW.Cars.Add(new Car { CarID = 117, Model = "Golf" });
makerVW.Cars.Add(new Car { CarID = 118, Model = "Jetta" });
makerVW.Cars.Add(new Car { CarID = 119, Model = "Beetle" });
Manufacturer makerTesla = new Manufacturer { ManufacturerID = 13, Name = "Tesla" };
makerTesla.Cars.Add(new Car { CarID = 120, Model = "Model 3" });
makerTesla.Cars.Add(new Car { CarID = 121, Model = "Model S" });
makerTesla.Cars.Add(new Car { CarID = 122, Model = "Model X" });
Manufacturer makerHyundai = new Manufacturer { ManufacturerID = 14, Name = "Hyundai" };
makerHyundai.Cars.Add(new Car { CarID = 123, Model = "Accent" });
makerHyundai.Cars.Add(new Car { CarID = 124, Model = "Elantra" });
makerHyundai.Cars.Add(new Car { CarID = 125, Model = "Sonata" });
Manufacturer makerMINI = new Manufacturer { ManufacturerID = 15, Name = "MINI" };
Manufacturer makerChevrolet = new Manufacturer { ManufacturerID = 16, Name = "Chevrolet" };
Manufacturer makerBMW = new Manufacturer { ManufacturerID = 17, Name = "BMW" };
Manufacturer makerChrysler = new Manufacturer { ManufacturerID = 18, Name = "Chrysler" };
Manufacturer makerLexus = new Manufacturer { ManufacturerID = 19, Name = "Lexus" };
Manufacturer makerMercedes = new Manufacturer { ManufacturerID = 20, Name = "Mercedes" };
Manufacturer makerPorsche = new Manufacturer { ManufacturerID = 21, Name = "Porsche" };
colCarMakers.Add(makerAudi);
colCarMakers.Add(makerFord);
colCarMakers.Add(makerVW);
colCarMakers.Add(makerTesla);
colCarMakers.Add(makerHyundai);
colCarMakers.Add(makerMINI);
colCarMakers.Add(makerChevrolet);
colCarMakers.Add(makerBMW);
colCarMakers.Add(makerChrysler);
colCarMakers.Add(makerLexus);
colCarMakers.Add(makerMercedes);
colCarMakers.Add(makerPorsche);
} catch (Exception) {
//
}
}
}
}
1 ответ
Проблема в том, что самая первая строка в каждом из ваших сеттеров:
<Setter Target="lblManufacturerName.FontSize" Value="18" />
нарушает работу всех Сеттеров. Это связано с тем, что вы пытаетесь получить доступ к элементу управления внутри шаблона данных - какой из элементов вы хотите изменить? Один, два или все из них - я полагаю, что все, но программа не знает этого.
Чтобы заставить ваш код работать, вам нужно сделать две вещи - удалить упомянутую строку из всех ваших сеттеров в MainPage - это должно заставить работать AdaptiveTrigger. Потом поменять lblManufacturerName.FontSize
вам придется изменить DataTemplate для работы с триггером. После ответа Джастина XL вы должны будете обернуть его в UserControl (или другой элемент управления с Content
). Как я уже проверял, что-то вроде этого должно работать:
<ScrollViewer VerticalScrollBarVisibility="Visible" Grid.Row="1">
<ListView Name="lvwMaster" ItemsSource="{x:Bind colAllCarMakers}" IsItemClickEnabled="True" ItemClick="lvwMaster_ItemClick">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:Manufacturer">
<UserControl>
<Border>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="vsSmallPhone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="10" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="lblManufacturerName.FontSize" Value="12" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="vsPhone">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="500" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="lblManufacturerName.FontSize" Value="18" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="vsTablet">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="720" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="lblManufacturerName.FontSize" Value="24" />
</VisualState.Setters>
</VisualState>
<VisualState x:Name="vsDesktop">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1024" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="lblManufacturerName.FontSize" Value="32" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<TextBlock Name="lblManufacturerName" FontSize="32" Text="{x:Bind Name}" TextWrapping="Wrap" />
</Border>
</UserControl>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>