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
中设置的 TextBlock
的 ContentPresenter
。如您所见,它们没有命名。如果我们想让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"
希望对您有所帮助。
为了显示结果,我按照下面提到的示例使用 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
中设置的 TextBlock
的 ContentPresenter
。如您所见,它们没有命名。如果我们想让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"
希望对您有所帮助。