我想实现以下内容:我在开头有一个空窗口,有3个按钮。当我单击按钮时,我想在窗口中生成Size*Size
按钮。对于按钮1,Size=6
,按钮2 Size=8
和按钮3 Size=0
,我认为我创建了UniformGrid
并将其大小绑定到{{ 1}},所以我可以改变按钮的数量。最初,Size
为0,因此无法看到任何按钮,然后当Size
更改时,按钮会显示。然而,这并不起作用。我正在尝试:
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>
最初为0,Size
将大小更改为6,Lvl1Command
更改为8等。Lvl2Command
只是一个数据结构,存储一些会影响其样式的属性按钮。怎么可以/我应该修改这个,以便当大小改变时,出现按钮的数量也会这样做?谢谢!
修改 在ViewModel构造函数中:
Fields
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
答案 0 :(得分:0)
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仍然绑定到空引用。您有两个选择:
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绑定将更新。