MVVM. Update controlek.

0

Witam!
Kolejne pytanie dotyczące MVVM. Otóż mam aplikację-grę " kółko i krzyżyk " . Jak zbindować dane z viewmodel do buttonow tak, żeby klikając w dany button w content nie wstawiał się wszędzie X albo O w sytuacji gdy binduję wszystkie buttony do jednego pola "Znak" . Jak to rozwiązać? Jakiś pomysł?

0

Brzydki kod jeśli chodzi o view, ale nie chcę mi się o tej godzinie myśleć, a obrazuje o co mniej więcej chodzi...

XAML -> wyświetlam listę list żeby otrzymać 3x3, pewnie można grida zastosować żeby było bardziej elegancko, ale co tam... Zawartość "mapy" jest widoczna w buttonach które są przypisane do komendy.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <ListView ItemsSource="{Binding Path=Fields}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ListView ItemsSource="{Binding}">
                        <ListView.ItemsPanel>
                            <ItemsPanelTemplate>
                                <StackPanel Orientation="Horizontal">
                                </StackPanel>
                            </ItemsPanelTemplate>
                        </ListView.ItemsPanel>
                        <ListView.ItemTemplate>
                            <DataTemplate>
                                <StackPanel>
                                    <Button MinWidth="20" MinHeight="20" Content="{Binding Path=Value}" Command="{Binding Path=MakeMove}" />
                                </StackPanel>
                            </DataTemplate>
                        </ListView.ItemTemplate>
                    </ListView>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
</Window>
namespace WpfApplication1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            ViewModel vm = new ViewModel();
            this.DataContext = vm;
        }
    }
}

Tutaj brzydota polega na tym, że komenda potrzebuję fielda i VM, ale tak jak pisałem, nie potrafię teraz myśleć, sam sobie poradzisz...

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.ComponentModel;

namespace WpfApplication1
{
    public class ViewModel 
    {
        private Field[][] _fields;
        public Field[][] Fields 
        {
            get { return _fields; }
            set { _fields = value;  }
        }

        private string _currentSymbol;

        public void MakeMove(Field target)
        {
            target.Value = _currentSymbol;

            _currentSymbol = (_currentSymbol == "O" ? "X" : "O");
        }

        public ViewModel()
        {
            _currentSymbol = "O";

            Fields = new Field[3][];
            for (int i = 0; i < 3; i++)
            {
                Fields[i] = new Field[3];
                for (int j = 0; j < 3; j++)
                {
                    Fields[i][j] = new Field(this);
                }
            }

        }
    }

    public class Field : INotifyPropertyChanged
    {
        private string _value;
        public string Value 
        {
            get { return _value; }
            set { _value = value; OnPropertyChanged("Value"); }
        }
        public ICommand MakeMove { get; set; }

        private ViewModel _vm;

        public Field(ViewModel vm)
        {
            _vm = vm;
            Value = "";

            MakeMove = new MakeMoveCommand(this, _vm);            
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public class MakeMoveCommand : ICommand
    {
        private Field _field;
        private ViewModel _vm;

        public bool CanExecute(object parameter)
        {
            return _field.Value.Length == 0;
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            _vm.MakeMove(_field);
        }

        public MakeMoveCommand(Field field, ViewModel vm)
        {
            _field = field;
            _vm = vm;
        }
    }

}
 
0

TO ZNOWU JA!

W załączniku łap projekt który jest kompletną grą w kółko i krzyżyk. Krótko pisząc View pobiera informacje za pomocą {Binding}, a zdarzenia obsługuje dzięki komendą (czyli... {Binding}!). ViewModel nic nie wiem o View. Są rzeczy które można zrobić na różne sposoby np. jak mają działać komendy? Czy samodzielnie mają zmienić pole, czy tylko poinformować ViewModel że zostały wykonane? Kolejna rzecz, to czy ViewModel ma przekazać komunikaty (Info), czy np. View sam ma zinterpretować jak poinformować użytkownika o tym, że np. kółko wygrało.

1 użytkowników online, w tym zalogowanych: 0, gości: 1