<!-- / --> <ListBox ItemsSource="{Binding UserWallet}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Width="32" Height="32" Source="{Binding Icon}"></Image> <Label Content="{Binding Name}"/> <Label Content="{Binding Amount}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
<!----> <DockPanel> <Label DockPanel.Dock="Top" Content=" "/> <ListBox ItemsSource="{Binding UserBuyings}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Label Content="{Binding Name}"/> <Label FontWeight="DemiBold" Content="{Binding Price}"/> <Label Content="{Binding Amount}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </DockPanel>
<UserControl ...> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <!----> <DockPanel> <Label DockPanel.Dock="Top" Content=" "/> <!----> <StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal"> <Label Content=" :"/> <Label Content="{Binding UserSumm}"/> </StackPanel> <!-- / --> <ListBox ... /> </DockPanel> <!----> <DockPanel Grid.Row="0" Grid.Column="1" .../> </Grid> </UserControl>
<Window ...> <Window.Resources> <!-- / --> <!-- DataType ( ) --> <DataTemplate DataType="{x:Type local:ProductVM}"> <StackPanel Orientation="Horizontal"> <Label Content="{Binding Name}"/> <Label FontWeight="DemiBold" Content="{Binding Price}"/> <Label Content="{Binding Amount}"/> </StackPanel> </DataTemplate> <!-- / --> <DataTemplate DataType="{x:Type local:MoneyVM}"> <StackPanel Orientation="Horizontal"> <Image Width="32" Height="32" Source="{Binding Icon}"></Image> <Label Content="{Binding Name}"/> <Label Content="{Binding Amount}"/> </StackPanel> </DataTemplate> </Window.Resources> <!-- ( ) VM - MainViewVM.cs --> <Window.DataContext> <local:MainViewVM/> </Window.DataContext> <!-- , , - ( ) --> <!-- DataContext DataContext --> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <local:UserView Margin="10" /> <local:AutomatView Grid.Column="1" Margin="10"/> </Grid> </Window>
public class MainViewVM : BindableBase { } public class ProductVM { } public class MoneyVM { }
<UserControl ...> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <!----> <DockPanel Grid.Row="0" Grid.Column="1"> <Label DockPanel.Dock="Top" Content=""/> <!----> <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom"> <Label Content=":"/> <Label Content="{Binding Credit}"/> </StackPanel> <!----> <ListBox ItemsSource="{Binding AutomataBank}" /> </DockPanel> <!-- --> <DockPanel Grid.Row="0" Grid.Column="0"> <Label DockPanel.Dock="Top" Content=""/> <ListBox ItemsSource="{Binding ProductsInAutomata}"/> </DockPanel> </Grid> </UserControl>
<!-- / --> <DataTemplate DataType="{x:Type local:ProductVM}"> <StackPanel Orientation="Horizontal"> <Button Visibility="{Binding IsBuyVisible}" Command="{Binding BuyCommand}">+</Button> ... <!-- / --> <DataTemplate DataType="{x:Type local:MoneyVM}"> <StackPanel Orientation="Horizontal"> <Button Visibility="{Binding IsInsertVisible}" Command="{Binding InsertCommand}">+</Button> ... <!----> <StackPanel Orientation="Horizontal" DockPanel.Dock="Bottom"> <Button Command="{Binding GetChange}" Margin="5"> </Button> ...
<Grid d:DataContext="{d:DesignInstance {x:Type local:MainViewVM}}">
public class MainViewVM : BindableBase { public int UserSumm { get; } public ObservableCollection<MoneyVM> UserWallet { get; } public ObservableCollection<ProductVM> UserBuyings { get; } public DelegateCommand GetChange { get; } public int Credit { get; } public ReadOnlyObservableCollection<MoneyVM> AutomataBank { get; } public ReadOnlyObservableCollection<ProductVM> ProductsInAutomata { get; } } public class ProductVM { public Visibility IsBuyVisible { get; } public DelegateCommand BuyCommand { get; } public string Name { get; } public string Price { get; } public int Amount { get; } } public class MoneyVM { public Visibility IsInsertVisible { get; } public DelegateCommand InsertCommand { get; } public string Icon { get; } public string Name { get; } public int Amount { get; } }
public class MainViewVM : BindableBase { public MainViewVM() { _user = new User(); } public int UserSumm => _user.UserSumm; //... private User _user; }
//, , , public struct Banknote { //, public static readonly IReadOnlyList<Banknote> Banknotes = new[] { new Banknote("", 1, true), new Banknote(" ", 2, true), new Banknote(" ", 5, true), new Banknote(" ", 10, false), new Banknote(" ", 50, false), new Banknote(" ", 100, false), }; private Banknote(string name, int nominal, bool isCoin) { Name = name; Nominal = nominal; IsCoin = isCoin; } public string Name { get; } public int Nominal { get; } public bool IsCoin { get; } // . }
public class MoneyStack { public MoneyStack(Banknote banknote, int amount) { Banknote = banknote; Amount = amount; } public Banknote Banknote { get; } public int Amount { get; } }
public class User { public User() { // _userWallet = new ObservableCollection<MoneyStack> (Banknote.Banknotes.Select(b => new MoneyStack(b, 10))); UserWallet = new ReadOnlyObservableCollection<MoneyStack>(_userWallet); } public ReadOnlyObservableCollection<MoneyStack> UserWallet { get; } private readonly ObservableCollection<MoneyStack> _userWallet; ... }
public MainViewVM() { _user = new User(); // UserWallet = new ObservableCollection<MoneyVM>(_user.UserWallet.Select(ms => new MoneyVM(ms))); // ((INotifyCollectionChanged) _user.UserWallet).CollectionChanged += (s, a) => { if(a.NewItems?.Count == 1) UserWallet.Add(new MoneyVM(a.NewItems[0] as MoneyStack)); if (a.OldItems?.Count == 1) UserWallet.Remove(UserWallet.First(mv => mv.MoneyStack == a.OldItems[0])); }; }
public class MoneyVM { public MoneyStack MoneyStack { get; } public MoneyVM(MoneyStack moneyStack) { MoneyStack = moneyStack; } public Visibility IsInsertVisible => InsertCommand == null ? Visibility.Collapsed : Visibility.Visible; public DelegateCommand InsertCommand { get; } public string Icon => MoneyStack.Banknote.IsCoin ? "..\\Images\\coin.jpg" : "..\\Images\\banknote.png"; public string Name => MoneyStack.Banknote.Name; public int Amount => MoneyStack.Amount; }
public class Product { //, web service public static IReadOnlyList<Product> Products = new List<Product>() { new Product("",12), new Product(" ", 25), new Product("",6), new Product("",23), new Product("",19), new Product("",670), }; private Product(string name, int price) { Name = name; Price = price; } public string Name { get; } public int Price { get; } } ProductStack.cs: public class ProductStack { public ProductStack(Product product, int amount) { Product = product; Amount = amount; } public Product Product { get; } public int Amount { get; } }
public class User { public User() { ... // UserBuyings = new ReadOnlyObservableCollection<ProductStack>(_userBuyings); } public ReadOnlyObservableCollection<ProductStack> UserBuyings { get; } private readonly ObservableCollection<ProductStack> _userBuyings = new ObservableCollection<ProductStack>(); ... }
public class ProductVM { public ProductStack ProductStack { get; } public ProductVM(ProductStack productStack) { ProductStack = productStack; } public Visibility IsBuyVisible => BuyCommand == null ? Visibility.Collapsed : Visibility.Visible; public DelegateCommand BuyCommand { get; } public string Name => ProductStack.Product.Name; public string Price => $"({ProductStack.Product.Price} .)"; public Visibility IsAmountVisible => BuyCommand == null ? Visibility.Collapsed : Visibility.Visible; public int Amount => ProductStack.Amount; }
public MainViewVM() { ... // UserBuyings = new ObservableCollection<ProductVM>(_user.UserBuyings.Select(ub => new ProductVM(ub))); ((INotifyCollectionChanged)_user.UserBuyings).CollectionChanged += (s, a) => { if (a.NewItems?.Count == 1) UserBuyings.Add(new ProductVM(a.NewItems[0] as ProductStack)); if (a.OldItems?.Count == 1) UserBuyings.Remove(UserBuyings.First(ub => ub.ProductStack == a.OldItems[0])); }; }
private static void Watch<T, T2> (ReadOnlyObservableCollection<T> collToWatch, ObservableCollection<T2> collToUpdate, Func<T2, object> modelProperty) { ((INotifyCollectionChanged)collToWatch).CollectionChanged += (s, a) => { if (a.NewItems?.Count == 1) collToUpdate.Add((T2)Activator.CreateInstance(typeof(T2), (T) a.NewItems[0])); if (a.OldItems?.Count == 1) collToUpdate.Remove(collToUpdate.First(mv => modelProperty(mv) == a.OldItems[0])); }; }
Watch(_user.UserWallet, UserWallet, um => um.MoneyStack); Watch(_user.UserBuyings, UserBuyings, ub => ub.ProductStack);
public class Automata { public Automata() { // _automataBank = new ObservableCollection<MoneyStack> (Banknote.Banknotes.Select(b => new MoneyStack(b, 100))); AutomataBank = new ReadOnlyObservableCollection<MoneyStack>(_automataBank); // _productsInAutomata = new ObservableCollection<ProductStack>(Product.Products.Select(p => new ProductStack(p, 100))); ProductsInAutomata = new ReadOnlyObservableCollection<ProductStack>(_productsInAutomata); } public ReadOnlyObservableCollection<MoneyStack> AutomataBank { get; } private readonly ObservableCollection<MoneyStack> _automataBank; public ReadOnlyObservableCollection<ProductStack> ProductsInAutomata { get; } private readonly ObservableCollection<ProductStack> _productsInAutomata; public int Credit { get; } }
public class MainViewVM : BindableBase { public MainViewVM() { ... _automata = new Automata(); // AutomataBank = new ObservableCollection<MoneyVM>(_automata.AutomataBank.Select(a => new MoneyVM(a))); Watch(_automata.AutomataBank, AutomataBank, a => a.MoneyStack); // ProductsInAutomata = new ObservableCollection<ProductVM>(_automata.ProductsInAutomata.Select(ap => new ProductVM(ap))); Watch(_automata.ProductsInAutomata, ProductsInAutomata, p => p.ProductStack); } ... private Automata _automata; }
PurchaseManager.cs: public class PurchaseManager { public User User { get; } = new User(); public Automata Automata { get; } = new Automata(); } MainView.cs: public class MainViewVM : BindableBase { private PurchaseManager _manager; public MainViewVM() { _manager = new PurchaseManager(); _user = _manager.User; _automata = _manager.Automata; ... } ... }
public MoneyVM(MoneyStack moneyStack, PurchaseManager manager = null) { MoneyStack = moneyStack; if (manager != null) // Null, , DelegateCommand InsertCommand = new DelegateCommand(()=>{ manager.InsertMoney(MoneyStack.Banknote); }); }
public void InsertMoney(Banknote banknote) { if (User.GetBanknote(banknote)) // , Automata.InsertBanknote(banknote); // }
// MoneyStack , / // false internal bool GetBanknote(Banknote banknote) { if(_userWallet.FirstOrDefault(ms => ms.Banknote.Equals(banknote))?.PullOne() ?? false) { RaisePropertyChanged(nameof(UserSumm)); // ! return true; } return false; } // public int UserSumm { get { return _userWallet.Select(b => b.Banknote.Nominal * b.Amount).Sum(); } }
internal bool PullOne() { if (Amount > 0) { --Amount; return true; } return false; }
// internal void InsertBanknote(Banknote banknote) { _automataBank.First(ms => ms.Banknote.Equals(banknote)).PushOne(); Credit += banknote.Nominal; } // private int credit; public int Credit { get { return credit; } set { SetProperty(ref credit, value); }}
internal void PushOne() => ++Amount;
public class MoneyStack : BindableBase { ... private int _amount; public int Amount { get { return _amount; } set { SetProperty(ref _amount, value); } } }
... moneyStack.PropertyChanged += (s, a) => { RaisePropertyChanged(nameof(Amount)); };
_user.PropertyChanged += (s, a) => { RaisePropertyChanged(nameof(UserSumm)); };
_automata.PropertyChanged += (s, a) => { RaisePropertyChanged(nameof(Credit)); };
public ProductVM(ProductStack productStack, PurchaseManager manager = null) { ProductStack = productStack; productStack.PropertyChanged += (s, a) => { RaisePropertyChanged(nameof(Amount)); }; if (manager != null) BuyCommand = new DelegateCommand(() => { manager.BuyProduct(ProductStack.Product); }); }
public void BuyProduct(Product product) { if (Automata.BuyProduct(product)) User.AddProduct(product); }
internal bool BuyProduct(Product product) { if(Credit >= product.Price && _productsInAutomata.First(p=>p.Product.Equals(product)).PullOne()) { Credit -= product.Price; return true; } return false; }
internal void AddProduct(Product product) { var stack = _userBuyings.FirstOrDefault(b => b.Product == product); if (stack == null) _userBuyings.Add(new ProductStack(product, 1)); else stack.PushOne(); }
public int Amount { get { return _amount; } set { SetProperty(ref _amount, value); } } internal bool PullOne() { if (Amount > 0) { --Amount; return true; } return false; } internal void PushOne() => ++Amount;
... productStack.PropertyChanged += (s, a) => { RaisePropertyChanged(nameof(Amount)); };
class PurchaseManager { ... public void GetChange() { IEnumerable<MoneyStack> change; if (Automata.GetChange(out change)) User.AppendMoney(change); } } // Automata internal bool GetChange(out IEnumerable<MoneyStack> change) { change = new List<MoneyStack>(); if (Credit == 0) return false; var creditToReturn = Credit; var toReturn = new List<MoneyStack>(); foreach (var ms in _automataBank.OrderByDescending(m => m.Banknote.Nominal)) { if (creditToReturn >= ms.Banknote.Nominal) { toReturn.Add(new MoneyStack(ms.Banknote, creditToReturn / ms.Banknote.Nominal)); creditToReturn -= (creditToReturn / ms.Banknote.Nominal) * ms.Banknote.Nominal; } } if (creditToReturn != 0) return false; // , foreach (var ms in toReturn) // for (int i = 0; i < ms.Amount; ++i) // _automataBank.First(m => Equals(m.Banknote, ms.Banknote)).PullOne(); change = toReturn; Credit = 0; return true; } // User internal void AppendMoney(IEnumerable<MoneyStack> change) { foreach (var ms in change) for(int i=0; i<ms.Amount;++i) UserWallet.First(m => Equals(m.Banknote.Nominal, ms.Banknote.Nominal)).PushOne(); RaisePropertyChanged(nameof(UserSumm)); }
Source: https://habr.com/ru/post/339538/
All Articles