UWP 中如何使用 Visual State 修改网格列宽?

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

为了显示结果,我按照下面提到的示例使用 MyToolKit 包的数据网格:https://github.com/MyToolkit/MyToolkit/wiki/DataGrid

使用这个网格我可以显示结果。为了使网格响应,我想设置两个不同的列宽。一个用于 Narrow State,另一个用于 Wide State。 我在这里添加我的网格和视觉状态代码

<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>

视觉状态码

<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>

值未根据状态生效。 请给我解决这个问题的建议。

x:name 属性 设置为您要更改的网格列,然后在您的 VisualStateManager 中使用该名称 让我知道它是否有效!

我认为 Visual State 无法处理您的情况。在您的代码中,您在 VisualState.Setters 中使用了 colBillId.Width 来更改列的宽度。但是在您的 DataGrid 加载后,在名为 colBillId 的可视化树中没有控件。您可以在 Visual Studio 的 Live Visual Tree:

中找到它

对于每个 DataGridTextColumn,它是一个包含您在 DataGridTextColumn.Header 中设置的 TextBlockContentPresenter。如您所见,它们没有命名。如果我们想让VisualState.Setters中的Setter在页面显示后起作用,我们必须在可视化树中有命名的控件。作为测试,我们可以在 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>

如果页面宽度大于“641”,您会发现"BillId"变成红色。但是列的宽度不会改变。所以在你的情况下,Visual State 无法工作。

正如 Mirko Bellabarba 所说,我建议您使用 Width 中的星号 (*) 作为解决方法。例如:

<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>

我有一个适用于通用网格的解决方案,因此它也适用于您的数据网格。

为您的 DataGrid 命名,例如:

<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>

然后在您的视觉状态代码中像这样访问该列:

<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>

因此您必须将列作为可索引的列来处理。所以不要写 Target="colBillId.Width" 你应该使用 Target="MyDataGrid.Columns[0].Width"

希望对您有所帮助。