2016-11-22 11 views
0

以下を実装したい:最初に3つのボタンで空のウィンドウがある。ボタンをクリックすると、ウィンドウ内にSize*Sizeボタンを生成したいと思います。ボタン1はSize=6、ボタン2はSize=8、ボタン3はSize=0ですので、UniformGridを作成し、そのサイズをSizeにバインドすると、ボタンの数を変更できます。最初はSizeが0になるため、ボタンは表示されず、Sizeが変更されるとボタンが表示されます。しかし、これは機能しません。私がしようとしている:WPFを使用したC# - 実行時にサイズ変更可能なボタンのグリッドを作成する

<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に、Lvl2Commandなど8にFieldsは、ボタンのスタイルに影響を与えるいくつかのプロパティを保存するだけでデータ構造です。サイズを変更したときに表示されるボタンの数も変わらないように、どうすればこの問題を修正できますか?ありがとうございました!

のViewModelコンストラクタでEDIT

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; } } 
+1

あなたは 'Lvl1Command'、' Lvl2Command'、 'Lvl3Command'、' Fields'、 'Size'のviewModelコードを表示できますか? – ASh

+0

@AShはあなたがリクエストしたコードを追加しました! :) –

+0

あなたが話しているメソッドは、 'NotifyPropertyChanged'(インターフェイス名としてちょうどかなりです!)または' RaisePropertyChanged' ... 'OnPropertyChanged'という名前は、_handler_というイベント –

答えて

0

ViewModelはINotifyPropertyChangedを実装する必要があります。あなたはSizeプロパティの変更の通知を上げたい場合は、次に

public event PropertyChangedEventHandler PropertyChanged; 

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

それをこのように書きます:このコードを追加します

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がビューに渡されると、コレクションはItemsControlにバインドされます。コンストラクタでコレクションを満たす必要はなく、インスタンス化するだけです。

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

この方法では、あなたがコレクションの新しいインスタンスにあなたがしたいすべての時間を設定することができます、とのItemsControlが更新される結合:

2)サイズがであるのと同じ方法でフィールドのプロパティを実装結果として。

+0

すばらしき、ありがとう! :) –

関連する問題