0

i want to dynamically adjust the width of my List View/Items. So when the user changes the screen size of the App, the Listview automatically adjust to the perfect size. At the moment i`m using adaptiv triggers, but there i have to specifically define values for each possible size i want to support.

<VisualStateManager.VisualStateGroups>
 <VisualStateGroup>
  <VisualState>
   <VisualState.StateTriggers>
    <AdaptiveTrigger MinWindowWidth="1000"></AdaptiveTrigger>
   </VisualState.StateTriggers>
   <VisualState.Setters>
     <Setter Target="textBlockOne.(RelativePanel.Width)" Value="130" />
   </VisualState.Setters>

Every other element i can access and manipulate in the codebehind. Even the ListView Header is accessible. So it would be very nice if someone has a solution for accessing the values in the ListView DataTemplate.

Something like this would be awesome:

<ListView x:Name="testList">
 <ListView.Header>
  <StackPanel x:Name="TestListHeaderStackPanel">
 </ListView.Header>
 <ListView.ItemTemplate>
  <DataTemplate x:Name="DataTemplatedata">
   <Grid x:Name="GridTest">
    .....
   </Grid>
  </DataTemplate>
 <ListView.ItemTemplate>
<ListView>

    private void OnPageSizeChanged(object sender, SizeChangedEventArgs args)
    {
     GridTest.ColumnDefinitions[1].Width=20;
    }
Olias
  • 401
  • 5
  • 17
  • 1
    I'm not 100% sure it fits for you, but have you seen UWP Community toolkit? The adaptivegridview is easy to use... maybe it also covers your usecase: https://developer.microsoft.com/en-us/windows/uwp-community-toolkit/controls/adaptivegridview.htm – gregkalapos Sep 15 '16 at 16:10
  • Can you define what "the perfect size" means? If by this you mean a fraction of the screen width then this can be achieved by putting the ListView inside a grid column that uses '*' sizing to be proportional to screen width. – ibebbs Sep 15 '16 at 19:47
  • @ibebbs Do you have an example, because when i`m trying it the Items do not scale properly, the header does. – Olias Sep 16 '16 at 10:31
  • Have you set a specific size on the ```ListView.ItemTemplate``` or any of it's children? This will prevent it resizing correctly. Typically you should avoid specifying sizes of elements in pixels and rely on autosizing where possible. You should also ensure the ```ListView.HorizontalContentAlignment``` and ```ListBox.VerticalContentAlignment``` properties are set to "Stretch" (you may need to edit the ```ItemContainerStyle``` to ensure this is correct). – ibebbs Sep 16 '16 at 11:39
  • @ibebbs THX you were right i only had to add an ItemContainerSyle like here: [link](http://stackoverflow.com/questions/15067309/listviewitem-wont-stretch-to-the-width-of-a-listview) Unbelievable how hard finding this solution can be. – Olias Oct 07 '16 at 15:50

1 Answers1

1

Every other element i can access and manipulate in the codebehind. Even the ListView Header is accessible. So it would be very nice if someone has a solution for accessing the values in the ListView DataTemplate.

To read the value of DataTemplate is possible, but to change the value of a already rendered ListView according to the DataTemplate Value would be a problem. And it is not recommended to do it this way.

As a workaround you can use databinding to change the Width of inner Grid. You can bind to Grid.Width to a Property of your ViewModel object ( let's say GridWidth ):

<StackPanel VerticalAlignment="Center">
        <ListView Name="lvImgs">
            <ListView.ItemTemplate>
                <DataTemplate>
                        <Grid Width="{Binding GridWidth}">
                            <Image  Source="{Binding ImageSource}"/>
                        </Grid>
                    </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button Name="btnChange" Click="btnChange_Click">Click Me to change Item Size</Button>
</StackPanel>

And change the GridWidth in CoreWindow.SizeChanged event:

Window.Current.CoreWindow.SizeChanged += CoreWindow_SizeChanged;
private void CoreWindow_SizeChanged(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.WindowSizeChangedEventArgs args)
{
    var widnowWidth = args.Size.Width;
    foreach (Model item in lvImgs.Items)
    {
        item.GridWidth = 500;
    }
}

And here is the Model class:

public class Model:INotifyPropertyChanged
{
    public Uri ImageSource{get;set;}
    public double _gridWidth;
    public double GridWidth
    {
        get { return _gridWidth; }
        set {
            _gridWidth = value;
            RaisePropertyChanged();
        }
    }

    public void RaisePropertyChanged([CallerMemberName]string name="")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }

    }
    public event PropertyChangedEventHandler PropertyChanged;
}

And here is the complete Demo: DynamicListViewSample.

Elvis Xia - MSFT
  • 10,801
  • 1
  • 13
  • 24