Sagar
Sagar

Reputation: 421

How To Modify Grid Column Width Using Visual State in UWP?

For showing results, I am using Data Grid of MyToolKit Package by following below mentioned example: https://github.com/MyToolkit/MyToolkit/wiki/DataGrid

Using this Grid I am able to show the results. In Order to make grid Responsive I want to set two different Column widths. One is for Narrow State and another one is for Wide State. Here I am adding my grid and visual state code

<controls:DataGrid.Columns>
    <controls:DataGridTextColumn Binding="{Binding billId}" d:DataContext="{d:DesignInstance Type=models:PendingBillDetail}" x:Name="colBillId" >
        <controls:DataGridTextColumn.Header>
            <TextBlock Name="txtBillId" Text="BillId" Foreground="Green" />
        </controls:DataGridTextColumn.Header>
    </controls:DataGridTextColumn>
</controls:DataGrid.Columns>

visual state code

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="wideView">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="641" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="colBillId.Width" Value="200" />
                <Setter Target="svPendingBillsList.VerticalScrollBarVisibility" Value="Disabled" />
            </VisualState.Setters>
        </VisualState>
        <VisualState x:Name="narrowView">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="colBillId.Width" Value="10" />
                <Setter Target="svPendingBillsList.HorizontalScrollBarVisibility" Value="Auto" />
                <Setter Target="svPendingBillsList.VerticalScrollBarVisibility" Value="Disabled" />
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

Values are not effecting according to the state. Please give me your suggestions to solve this issue.

Upvotes: 1

Views: 2937

Answers (3)

Alex Witkowski
Alex Witkowski

Reputation: 555

I have a Solution that works for common Grid so it schould also work for your DataGrid.

Give your DataGrid a name like:

<controls:DataGrid x:Name="MyDataGrid">
    <controls:DataGrid.Columns>
        <controls:DataGridTextColumn Binding="{Binding billId}" d:DataContext="{d:DesignInstance Type=models:PendingBillDetail}" x:Name="colBillId" >
            <controls:DataGridTextColumn.Header>
                <TextBlock Name="txtBillId" Text="BillId" Foreground="Green" />
            </controls:DataGridTextColumn.Header>
        </controls:DataGridTextColumn>
    </controls:DataGrid.Columns>
</controls:DataGrid>

And then acces the Column like this in your visual state code:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="wideView">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="641" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="MyDataGrid.Columns[0].Width" Value="200" />
                <Setter Target="svPendingBillsList.VerticalScrollBarVisibility" Value="Disabled" />
            </VisualState.Setters>
        </VisualState>
        <VisualState x:Name="narrowView">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="MyDataGrid.Columns[0].Width" Value="10" />
                <Setter Target="svPendingBillsList.HorizontalScrollBarVisibility" Value="Auto" />
                <Setter Target="svPendingBillsList.VerticalScrollBarVisibility" Value="Disabled" />
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

So you have to handle the columns as an indexable. So instead of writing Target="colBillId.Width" you should use Target="MyDataGrid.Columns[0].Width"

Hope that helps.

Upvotes: 0

Jay Zuo
Jay Zuo

Reputation: 15758

I think Visual State can't work with your case. In your code, you used colBillId.Width in VisualState.Setters to change the column's width. But after your DataGrid loaded, there is no control in the Visual Tree named colBillId. You can find this in Visual Studio's Live Visual Tree:

enter image description here

For each DataGridTextColumn, it's a ContentPresenter that contains the TextBlock you've set in DataGridTextColumn.Header. And as you can see, they are not named. If we want the Setter in VisualState.Setters to work after the page displayed, we must have the named control in visual tree. As a test, we can use following code in Visual State:

<VisualStateManager.VisualStateGroups>
    <VisualStateGroup>
        <VisualState x:Name="wideView">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="641" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="colBillId.Width" Value="200" />
                <Setter Target="txtBillId.Foreground" Value="Red" />
            </VisualState.Setters>
        </VisualState>
        <VisualState x:Name="narrowView">
            <VisualState.StateTriggers>
                <AdaptiveTrigger MinWindowWidth="0" />
            </VisualState.StateTriggers>
            <VisualState.Setters>
                <Setter Target="colBillId.Width" Value="50" />
                <Setter Target="txtBillId.Foreground" Value="Green" />
            </VisualState.Setters>
        </VisualState>
    </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

You will find "BillId" become red if the page's width larger than "641". However the column's width doesn't change. So in your case, Visual State can't work.

As Mirko Bellabarba said, I'd suggest you use Star (*) sizing in Width as a workaround. For example:

<controls:DataGrid.Columns>
    <controls:DataGridTextColumn Width="*" Binding="{Binding billId}" d:DataContext="{d:DesignInstance Type=models:PendingBillDetail}">
        <controls:DataGridTextColumn.Header>
            <TextBlock Name="txtBillId" Foreground="Green" Text="BillId" />
        </controls:DataGridTextColumn.Header>
    </controls:DataGridTextColumn>
    <controls:DataGridTextColumn Width="2*" Binding="{Binding billId}" d:DataContext="{d:DesignInstance Type=models:PendingBillDetail}">
        <controls:DataGridTextColumn.Header>
            <TextBlock Foreground="Green" Text="BillId" />
        </controls:DataGridTextColumn.Header>
    </controls:DataGridTextColumn>
</controls:DataGrid.Columns>

Upvotes: 1

Mirko Bellabarba
Mirko Bellabarba

Reputation: 592

Set the x:name property to the Grid Column you want to change, then use that name in your VisualStateManager Let me know if it works!

Upvotes: 0

Related Questions