繁体   English   中英

使用WPF的C#-创建在运行时可调整大小的按钮网格

[英]C# with WPF - Creating a grid of buttons resizable at runtime

我要实现以下目的:我有一个空的窗口,开头有3个按钮。 单击按钮时,我想在窗口中生成“ Size*Size按钮。 对于按钮1, Size=6 ,对于按钮2 Size=8 ,对于按钮3 Size=0 ,所以我认为我将创建一个UniformGrid并将其大小绑定到Size ,以便可以更改当前按钮的数量。 最初,“ Size为0,因此看不到任何按钮,然后在“ Size更改时出现按钮。 但是,这不起作用。 我正在努力:

<Window x:Class="project.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="500" Width="700">
  <Grid>
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="Auto"/>
      <ColumnDefinition Width="*"/>
      <ColumnDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>

    <Menu Grid.Column="1" Margin="38,0,187,430" Background="White">
      <MenuItem Header="Level 1" FontFamily="Roboto" Height="32" Width="65"
                Command="{Binding Lvl1Command}"/>
      <MenuItem Header="Level 2" FontFamily="Roboto" Height="32" Width="65"
                Command="{Binding Lvl2Command}"/>
      <MenuItem Header="Level 3" FontFamily="Roboto" Height="32" Width="65"
                Command="{Binding Lvl3Command}"/>
    </Menu>

    <ItemsControl Grid.Column="2" ItemsSource="{Binding Fields}">
      <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
          <UniformGrid Rows="{Binding Size}" Columns="{Binding Size}"/>
        </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <Button Focusable="False" RenderTransformOrigin="0.5, 0.5"
                  Width="30" Height="25" FontSize="24" FontWeight="Bold">
          </Button>
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>
  </Grid>
</Window>

Size最初为0, Lvl1Command将大小更改为6, Lvl1Command更改为8, Lvl2CommandFields只是存储一些会影响按钮样式的属性的数据结构。 我如何/应该对此进行修改,以便在“大小”更改时,出现的“按钮”数量也可以更改? 谢谢!

在ViewModel构造函数中编辑

Lvl1Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Easy); });
Lvl2Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Medium); });
Lvl3Command = new DelegateCommand(param => { SetUpGame(MLModel.Level.Hard); });

SetUpGame()看起来像这样(包括Field ):

private void SetUpGame(MLModel.Level level)
{
    UpCommand = new DelegateCommand(param => { _model.MoveUp(); RefreshTable(); });
    DownCommand = new DelegateCommand(param => { _model.MoveDown(); RefreshTable(); });
    LeftCommand = new DelegateCommand(param => { _model.MoveLeft(); RefreshTable(); });
    RightCommand = new DelegateCommand(param => { _model.MoveRight(); RefreshTable(); });

    // időzítő létrehozása
    _timer = new DispatcherTimer();
    _timer.Interval = TimeSpan.FromSeconds(1);
    _timer.Tick += new EventHandler(Timer_Tick);
    _timer.Start();

    _model.SetLevel(level);
    _model.NewGame();            
    Fields = new ObservableCollection<MLField>();
    for (Int32 i = 0; i < _model.Table.Size; i++)
    {
        for (Int32 j = 0; j < _model.Table.Size; j++)
        {
            Fields.Add(new MLField
            {
                Text = _model.Table[i, j],
                X = i,
                Y = j,
                Number = i * _model.Table.Size + j
            });
        }
    }
    RefreshTable();
}

然后Size

public Int32 Size { get { return _model.Size; } }

ViewModel必须实现INotifyPropertyChanged 添加此代码:

public event PropertyChangedEventHandler PropertyChanged;

public void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

然后,如果要引发有关Size属性更改的通知,请按以下方式编写:

public int Size
{
    get { return _Size; }
    set
    {
        if (_Size != value)
        {
            _Size = value;
            NotifyPropertyChanged();
        }
    }
}
private int _Size;

此外, Fields集合最初为null,并且在SetupGame实例化它时,不会引发任何通知,因此View仍绑定到null引用。 您有2个选择:

1) 在构造函数中初始化Fields集合 这样,将ViewModel传递给View时,可以将集合绑定到ItemsControl 不必将集合填充到构造函数中,只需对其进行实例化即可。

2) 以相同的方式实现Fields属性

public ObservableCollection<MLField> Fields
{
    get { return _Fields; }
    set
    {
        if (_Fields != value)
        {
            _Fields = value;
            NotifyPropertyChanged();
        }
    }
}
private ObservableCollection<MLField> _Fields;

这样,您可以在每次需要的时候设置一个新的集合实例,并且ItemsControl绑定将随之更新。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM