3

I have used the VisualStateManager to hide (collapse) an image control in a UWP app before, so I know it works. But in this one example (below), it does not. I cannot figure out why the big image (called imgCarDetail) does not disappear and reappear as I stretch the page wider and narrower. I think it might be related to the data binding, but I cannot see why that would effect it.

Any suggestions are welcome.

MainPage.xaml

<Page
x:Class="StackoverflowExample.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:StackoverflowExample"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:data="using:StackoverflowExample.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 StackoverflowExample.Classes;
using System;
using System.Collections.ObjectModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace StackoverflowExample {
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) {
            //
        } 
    }

}
}

This might seem like a lot of code, but I want to give you everything you need to run and test the app, so here is the additional code you'll need to make it work.

Car.cs

namespace StackoverflowExample.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 StackoverflowExample.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 StackoverflowExample.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) {
            //
        }
    }
}
}
ThePeter
  • 883
  • 1
  • 7
  • 15

1 Answers1

1

The problem is that the very first line in each of your Setters:

<Setter Target="lblManufacturerName.FontSize" Value="18" />

breaks the working of all Setters. This is because you are trying to access the control that is inside the DataTemplate - which of the items you would like to change? One, Two, or all of them - I suppose that all, but program doesn't know that.

To make your code work you will need to do two things - throw out the mentioned line from all of your setters in MainPage - this should make the AdaptiveTrigger working. Then to change lblManufacturerName.FontSize you will have to modify the DataTemplate to work with the trigger. Following Justin XL answer you will have to wrap it in UserControl (or other Control with Content). As I've tested, something like this should work:

<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>
Community
  • 1
  • 1
Romasz
  • 29,662
  • 13
  • 79
  • 154
  • That was perfect. Thank you Romasz. It wasn't throwing an error, so I had no reason to suspect it was causing a problem. – ThePeter Jan 19 '17 at 01:01