在 UWP 中使用 StyleSelector 更改扫雷游戏的 ListViewItem 样式
Using StyleSelector in UWP to Change ListViewItem Styles for Minesweeper Game
我正在为 class 制作一个扫雷克隆版。基本游戏板是通过代码生成的,但它是一系列包含 Tile
行对象的 ListView
列。此代码生成 ListViews
(工作正常):
// Create as many lists as necessary to fill the board according to the size specified
void createGameBoard(bool erase = true)
{
// Erase any previous game
if(erase)
{
for(int i = mainGameBoard.Children.Count; i > 0; i--)
{
mainGameBoard.Children.RemoveAt(i - 1);
}
}
// Main Game Board
// column 0 column 1 column 2
// tile 0,0 tile 1,0 tile 2,0
// tile 0,1 tile 1,1 tile 2,1
// tile 0,2 tile 1,2 tile 2,2
// Create a new list view for each game board column
for(uint col = 0; col < minesweepGame.Width; col++)
{
ListView column = new ListView();
column.Name = col.ToString();
column.SelectionMode = ListViewSelectionMode.None;
column.IsItemClickEnabled = true;
column.ItemClick += Column_ItemClick;
///column.ItemContainerStyleSelector.SelectStyle()
// Fill the column with tiles
Tile[] columnTiles = new Tile[minesweepGame.Width];
for(uint row = 0; row < minesweepGame.Width; row++)
{
columnTiles[row] = minesweepGame.TileList[col, row];
}
column.ItemsSource = columnTiles;
// Append the newly created column to the main game board (in order of creation)
mainGameBoard.Children.Add(column);
}
}
这会产生带有动画的干净网格。
UWP Minesweeper using ListViews
我想在向用户显示项目时设置不同的样式(单击后,图块会变暗并且数字颜色不同)。所以我查看了 documentation and examples,并创建了一个 StyleSelector
:
public class ColumnTileSelector : StyleSelector
{
private Style Tile0 = new Style(typeof(ListViewItem));
private Style Tile1 = new Style(typeof(ListViewItem));
private Style Tile2 = new Style(typeof(ListViewItem));
private Style Tile3 = new Style(typeof(ListViewItem));
private Style Tile4 = new Style(typeof(ListViewItem));
protected override Style SelectStyleCore(object item, DependencyObject container)
{
Tile tile = (Tile)item;
if(tile.IsShownGraphically)
{
switch(tile.AdjacentMines)
{
case 0:
Tile0.Setters.Add(new Setter(Control.BackgroundProperty, Colors.Red));
return Tile0;
case 1:
return Tile1;
case 2:
return Tile2;
case 3:
return Tile3;
case 4:
return Tile4;
default:
return Tile0;
}
}
else
{
return Tile0;
}
}
}
我之前也曾在 XAML
:
中创建过样式
<!-- style the game grid tiles -->
<Page.Resources>
<Style TargetType="ListViewItem">
<Setter Property="MinWidth" Value="30"/>
<Setter Property="MinHeight" Value="30"/>
<Setter Property="MaxWidth" Value="30"/>
<Setter Property="MaxHeight" Value="30"/>
<Setter Property="Padding" Value="2, 2, 2, 2"/>
<Setter Property="BorderBrush" Value="SlateGray"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="ExtraBlack"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile0">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Transparent"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile1">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile2">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Green"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile3">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile4">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkOrange"/>
</Style>
<Style TargetType="StackPanel" x:Key="mainGameBoard">
<Setter Property="BorderBrush" Value="SlateGray"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
<local:ColumnTileSelector x:Key="tileColor"/>
</Page.Resources>
然而,实际上没有任何效果。
- 如何在视图代码中引用
XAML
中的样式?
- 更重要的是,如何指定我的
ListViews
应该使用 ColumnTileSelector
?
- 在生成
ListViews
的代码中,我注释掉了///column.ItemContainerStyleSelector.SelectStyle()
。可以在这里指定我的 ColumnTileSelector
class 吗?我很困惑。
文档并不清楚事物是如何连接在一起的。我原则上理解,但是 none 我看到的例子详细说明了为什么事情会这样反应。
<Page>
<Page.Resources>
<Style TargetType="ListViewItem" x:Key="Tile1">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<support:ColumnStyleSelector x:Key="ColumnStyleSelector"
Tile1="{StaticResource Tile1}"/>
</Page.Resources>
<Grid>
<ListView ItemContainerStyleSelector="{StaticResource ColumnStyleSelector}"/>
</Page>
- 制作样式 Tile1、Tile2 等 public ColumnStyleSelector 的属性
- 将样式放入页面资源
- 将ColumnStyleSelector放在页面资源中
- 在 ColumnStyleSelector 属性中引用资源中的样式
在视图代码中引用样式需要几个步骤。首先,在视图中创建一个页面类型的变量:static MainPage mainPage;
第二,在页面构造函数中初始化它:mainPage = this;
第三,在视图控制器中使用样式:mainPage.Resources["TileExploded"] as Style;
要指定列表视图必须以编程方式使用哪个 StyleSelector
,请使用此代码:column.ItemContainerStyleSelector = new ColumnStyleSelector();
,其中 column
是 ListView
。
因此,可以使用 StyleSelector
:
中的逻辑呈现具有不同样式的元素ListViewItem
// Selects what style applies to a list view item according to that item's properties when it is rendered
public class ColumnStyleSelector : StyleSelector
{
protected override Style SelectStyleCore(object item, DependencyObject container)
{
Tile tile = (Tile)item;
if(tile.Type == (int)TileType.ExplodedMine)
{
return mainPage.Resources["TileExploded"] as Style;
}
else if(tile.IsRevealed == true && tile.IsShownGraphically == true)
{
switch(tile.AdjacentMines)
{
case 0:
return mainPage.Resources["Tile0"] as Style;
case 1:
return mainPage.Resources["Tile1"] as Style;
case 2:
return mainPage.Resources["Tile2"] as Style;
case 3:
return mainPage.Resources["Tile3"] as Style;
case 4:
return mainPage.Resources["Tile4"] as Style;
default:
return mainPage.Resources["ListViewItem"] as Style;
}
}
else
{
return mainPage.Resources["ListViewItem"] as Style;
}
}
}
当然,这可以使用程序特定的任何逻辑,关键语句是return mainPage.Resources["XAML Resource Style Key Here"] as Style;
我正在为 class 制作一个扫雷克隆版。基本游戏板是通过代码生成的,但它是一系列包含 Tile
行对象的 ListView
列。此代码生成 ListViews
(工作正常):
// Create as many lists as necessary to fill the board according to the size specified
void createGameBoard(bool erase = true)
{
// Erase any previous game
if(erase)
{
for(int i = mainGameBoard.Children.Count; i > 0; i--)
{
mainGameBoard.Children.RemoveAt(i - 1);
}
}
// Main Game Board
// column 0 column 1 column 2
// tile 0,0 tile 1,0 tile 2,0
// tile 0,1 tile 1,1 tile 2,1
// tile 0,2 tile 1,2 tile 2,2
// Create a new list view for each game board column
for(uint col = 0; col < minesweepGame.Width; col++)
{
ListView column = new ListView();
column.Name = col.ToString();
column.SelectionMode = ListViewSelectionMode.None;
column.IsItemClickEnabled = true;
column.ItemClick += Column_ItemClick;
///column.ItemContainerStyleSelector.SelectStyle()
// Fill the column with tiles
Tile[] columnTiles = new Tile[minesweepGame.Width];
for(uint row = 0; row < minesweepGame.Width; row++)
{
columnTiles[row] = minesweepGame.TileList[col, row];
}
column.ItemsSource = columnTiles;
// Append the newly created column to the main game board (in order of creation)
mainGameBoard.Children.Add(column);
}
}
这会产生带有动画的干净网格。
UWP Minesweeper using ListViews
我想在向用户显示项目时设置不同的样式(单击后,图块会变暗并且数字颜色不同)。所以我查看了 documentation and examples,并创建了一个 StyleSelector
:
public class ColumnTileSelector : StyleSelector
{
private Style Tile0 = new Style(typeof(ListViewItem));
private Style Tile1 = new Style(typeof(ListViewItem));
private Style Tile2 = new Style(typeof(ListViewItem));
private Style Tile3 = new Style(typeof(ListViewItem));
private Style Tile4 = new Style(typeof(ListViewItem));
protected override Style SelectStyleCore(object item, DependencyObject container)
{
Tile tile = (Tile)item;
if(tile.IsShownGraphically)
{
switch(tile.AdjacentMines)
{
case 0:
Tile0.Setters.Add(new Setter(Control.BackgroundProperty, Colors.Red));
return Tile0;
case 1:
return Tile1;
case 2:
return Tile2;
case 3:
return Tile3;
case 4:
return Tile4;
default:
return Tile0;
}
}
else
{
return Tile0;
}
}
}
我之前也曾在 XAML
:
<!-- style the game grid tiles -->
<Page.Resources>
<Style TargetType="ListViewItem">
<Setter Property="MinWidth" Value="30"/>
<Setter Property="MinHeight" Value="30"/>
<Setter Property="MaxWidth" Value="30"/>
<Setter Property="MaxHeight" Value="30"/>
<Setter Property="Padding" Value="2, 2, 2, 2"/>
<Setter Property="BorderBrush" Value="SlateGray"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="ExtraBlack"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile0">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Transparent"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile1">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile2">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Green"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile3">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="Red"/>
</Style>
<Style TargetType="ListViewItem" x:Key="Tile4">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkOrange"/>
</Style>
<Style TargetType="StackPanel" x:Key="mainGameBoard">
<Setter Property="BorderBrush" Value="SlateGray"/>
<Setter Property="BorderThickness" Value="0"/>
</Style>
<local:ColumnTileSelector x:Key="tileColor"/>
</Page.Resources>
然而,实际上没有任何效果。
- 如何在视图代码中引用
XAML
中的样式? - 更重要的是,如何指定我的
ListViews
应该使用ColumnTileSelector
? - 在生成
ListViews
的代码中,我注释掉了///column.ItemContainerStyleSelector.SelectStyle()
。可以在这里指定我的ColumnTileSelector
class 吗?我很困惑。
文档并不清楚事物是如何连接在一起的。我原则上理解,但是 none 我看到的例子详细说明了为什么事情会这样反应。
<Page>
<Page.Resources>
<Style TargetType="ListViewItem" x:Key="Tile1">
<Setter Property="Background" Value="LightGray"/>
<Setter Property="Foreground" Value="DarkBlue"/>
</Style>
<support:ColumnStyleSelector x:Key="ColumnStyleSelector"
Tile1="{StaticResource Tile1}"/>
</Page.Resources>
<Grid>
<ListView ItemContainerStyleSelector="{StaticResource ColumnStyleSelector}"/>
</Page>
- 制作样式 Tile1、Tile2 等 public ColumnStyleSelector 的属性
- 将样式放入页面资源
- 将ColumnStyleSelector放在页面资源中
- 在 ColumnStyleSelector 属性中引用资源中的样式
在视图代码中引用样式需要几个步骤。首先,在视图中创建一个页面类型的变量:
static MainPage mainPage;
第二,在页面构造函数中初始化它:mainPage = this;
第三,在视图控制器中使用样式:mainPage.Resources["TileExploded"] as Style;
要指定列表视图必须以编程方式使用哪个
StyleSelector
,请使用此代码:column.ItemContainerStyleSelector = new ColumnStyleSelector();
,其中column
是ListView
。
因此,可以使用 StyleSelector
:
ListViewItem
// Selects what style applies to a list view item according to that item's properties when it is rendered
public class ColumnStyleSelector : StyleSelector
{
protected override Style SelectStyleCore(object item, DependencyObject container)
{
Tile tile = (Tile)item;
if(tile.Type == (int)TileType.ExplodedMine)
{
return mainPage.Resources["TileExploded"] as Style;
}
else if(tile.IsRevealed == true && tile.IsShownGraphically == true)
{
switch(tile.AdjacentMines)
{
case 0:
return mainPage.Resources["Tile0"] as Style;
case 1:
return mainPage.Resources["Tile1"] as Style;
case 2:
return mainPage.Resources["Tile2"] as Style;
case 3:
return mainPage.Resources["Tile3"] as Style;
case 4:
return mainPage.Resources["Tile4"] as Style;
default:
return mainPage.Resources["ListViewItem"] as Style;
}
}
else
{
return mainPage.Resources["ListViewItem"] as Style;
}
}
}
当然,这可以使用程序特定的任何逻辑,关键语句是return mainPage.Resources["XAML Resource Style Key Here"] as Style;