【问题标题】:Using StyleSelector in UWP to Change ListViewItem Styles for Minesweeper Game在 UWP 中使用 StyleSelector 更改扫雷游戏的 ListViewItem 样式
【发布时间】:2018-04-27 02:12:45
【问题描述】:

我正在为班级制作一个扫雷克隆。基本的游戏板是通过代码生成的,但它是一系列ListView 列,其中包含Tile 对象的行。此代码生成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

我想在向用户显示项目时以不同的方式设置项目(单击后,图块会变暗并具有不同颜色的数字)。所以我查看了documentationexamples,并创建了一个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>

但是,实际上没有任何效果。

  1. 如何在视图代码中引用 XAML 中的样式?
  2. 更重要的是,如何指定我的ListViews 应该使用ColumnTileSelector
  3. 在生成ListViews 的代码中,我注释掉了///column.ItemContainerStyleSelector.SelectStyle()。是否可以在这里指定我的ColumnTileSelector 课程?我很困惑。

文档并不清楚事物是如何连接在一起的。我原则上理解,但我看到的例子都没有说明为什么事情会如此反应。

【问题讨论】:

    标签: c# xaml listview uwp listviewitem


    【解决方案1】:
    <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>
    
    1. 将样式 Tile1、Tile2 等设为 ColumnStyleSelector 的公共属性
    2. 将样式放入页面资源中
    3. 将 ColumnStyleSelector 放在页面资源中
    4. 在 ColumnStyleSelector 属性中引用资源中的样式

    【讨论】:

    • 您能详细说明第 3 点和第 4 点吗?第 3 点给了我一个错误:'support' is an undeclared prefix. 使用&lt;local:... /&gt; 时也会发生同样的情况。对于第 4 点,如何做到这一点? column.ItemContainerStyleSelector...
    • 我有 &lt;local:ColumnStyleSelector x:Key="ColumnStyleSelector" Tile0="{StaticResource Tile0}".../&gt;column.ItemContainerStyleSelector = new ColumnStyleSelector(); 但是,属性 public Style Tile0 { get; set; } 似乎没有引用任何 XAML 样式。
    • support 是 ColumnSelector 类的命名空间。正如在 xaml 顶部使用 xmlns:support="using:Standard" ItemContainer 声明的那样。您的 column.ItemContainerStyle 需要通过“{StaticResource ColumnStyleSelector}”设置为样式页面上的资源需要由 Page.Resouurces["Tile0"] 访问
    • 我不记得我当时是否能够使用您的答案,但我接受它是为了感谢您提供它的工作。
    【解决方案2】:
    1. 在视图代码中引用样式需要几个步骤。一、在视图中创建页面类型变量:static MainPage mainPage; 二、在页面构造函数中初始化:mainPage = this; 三、在视图控制器中使用样式:mainPage.Resources["TileExploded"] as Style;

    2. 要指定列表视图必须以编程方式使用哪个StyleSelector,请使用以下代码:column.ItemContainerStyleSelector = new ColumnStyleSelector();,其中columnListView

    因此,可以使用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;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 2012-11-15
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      • 2014-12-25
      相关资源
      最近更新 更多