2

我是 WPF 新手,我使用此代码用网格填充统一网格,

 public MainWindow()  
                {  
                    InitializeComponent();  
                    SolidColorBrush defaultBrush = new SolidColorBrush(Colors.Wheat);  
                    SolidColorBrush alternateBrush = new SolidColorBrush(Colors.Black);
                    Char L = 'A';
                    int N = 1;  
                    for (int i = 0; i < 64; i++)  
                    {  
                        Grid cell = new Grid();
                        if(N==9)
                         {   
                            N=1;
                            L++;
                         }

                        if ((i + i / 8) % 2 == 0)  
                        {  
                            cell.Name = L + N.ToString();
                            cell.Background = defaultBrush;  
                            ChessBoard.Children.Add(cell);  
                        }  
                        else  
                        {  
                            cell.Name = L + N.ToString();
                            cell.Background = alternateBrush;   
                            ChessBoard.Children.Add(cell);  
                        } 
                        N++
                    } 

然后,当我单击名为 ChessBoard 的制服网格时,我试图找出某个网格的名称。

       private void ChessBoard_MouseLeftButtonDown(object sender, MouseButtonEventArgs args)
        {


            var element = (UIElement)args.Source;
            element.Opacity = 0.5; 
        }

不透明度线是测试以确保我在正确的网格上,它可以工作并改变我点击的网格的不透明度。

我需要帮助的是找到元素的 Name 属性。

4

1 回答 1

11

好的,删除所有代码并重新开始。

如果您正在使用 WPF,那么您确实需要理解并接受WPF Mentality

作为一般规则,不鼓励在过程代码中创建或操作 UI 元素。相反,您创建一个适当的ViewModel,它将包含表示 UI 显示的状态和数据的所有相关属性,并使用DataBinding来反映这些属性。

这就是您在 WPF 中尝试的方式:

<Window x:Class="ChessBoardSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="350">
    <ItemsControl ItemsSource="{Binding Squares}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Rows="8" Columns="8"/>
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>

        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Button x:Name="Square"
                        Command="{Binding DataContext.SquareClickCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
                        CommandParameter="{Binding}">
                    <Button.Template>
                        <ControlTemplate TargetType="Button">
                            <Grid Background="{TemplateBinding Background}"/>
                        </ControlTemplate>
                    </Button.Template>
                </Button>

                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding IsBlack}" Value="True">
                        <Setter TargetName="Square" Property="Background" Value="Black"/>
                    </DataTrigger>

                    <DataTrigger Binding="{Binding IsBlack}" Value="False">
                        <Setter TargetName="Square" Property="Background" Value="Wheat"/>
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Window>

代码背后:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ChessBoard();
    }
}

视图模型:

public class ChessBoard
{
    public List<ChessSquare> Squares { get; private set; }

    public Command<ChessSquare> SquareClickCommand { get; private set; }

    public ChessBoard()
    {
        Squares = new List<ChessSquare>();

        for (int i = 0; i < 8; i++)
        {
            for (int j = 0; j < 8; j++)
            {
                Squares.Add(new ChessSquare() {Row = i, Column = j});
            }
        }

        SquareClickCommand = new Command<ChessSquare>(OnSquareClick);
    }

    private void OnSquareClick(ChessSquare square)
    {
        MessageBox.Show("You clicked on Row: " + square.Row + " - Column: " + square.Column);
    }
}

数据项:

public class ChessSquare
{
    public int Row { get; set; }

    public int Column { get; set; }

    public bool IsBlack { get { return (Row + Column) %2 == 1; }}        
}

命令类(MVVM 辅助类):

public class Command<T>: ICommand
{
    public Action<T> Action { get; set; }

    public void Execute(object parameter)
    {
        if (Action != null && parameter is T)
            Action((T)parameter);
    }

    public bool CanExecute(object parameter)
    {
        return IsEnabled;
    }

    private bool _isEnabled = true;
    public bool IsEnabled
    {
        get { return _isEnabled; }
        set
        {
            _isEnabled = value;
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, EventArgs.Empty);
        }
    }

    public event EventHandler CanExecuteChanged;

    public Command(Action<T> action)
    {
        Action = action;
    }
}

结果:

在此处输入图像描述

  • 虽然所有这些看起来像是“太多代码”,但如果你仔细观察,你会发现其中大部分实际上是可重用的、干净的代码,不依赖于 UI,而且我还为你提供了许多可重用的基础架构(比如Command班级)。

  • 我正在使用ItemsControl绑定到数据项的集合,而不是按程序创建 UI 元素。这是“让 WPF 完成它的工作”。

  • 主要思想是分离 UI 和 Logic,从而获得很多可扩展性和可维护性。
  • 请注意后面的代码是如何简化为DataContext = .... WPF 中的代码保留用于特定于 UI的代码,而不是与数据或逻辑相关的代码。
  • 我正在使用 aDelegateCommand来处理 Click 逻辑,而不是事件处理程序。这在 UI 元素由 ItemsControl 等动态创建的情况下很有用。
  • 还要注意该OnSquareClick()方法是如何针对您自己的简单、有状态数据项 ( ChessSquare) 而不是复杂的神秘 WPF UI 对象进行操作的。这就是您在 WPF 中编程的方式。您操作的是您的数据,而不是 UI。
  • 还要注意对属性使用DataTriggerIsBlack来动态更改背景颜色。
  • WPF 摇滚。只需将我的代码复制并粘贴到 a 中File -> New Project -> WPF Application,然后自己查看结果。
  • 我强烈建议您阅读所有链接的材料。如果您需要进一步的帮助,请告诉我。
于 2013-11-11T18:07:00.247 回答