Mvvm wpf téglalapok eseménye

Mvvm wpf téglalapok eseménye
2015-05-25T11:45:58+02:00
2015-05-28T09:56:06+02:00
2022-12-02T13:35:34+01:00
7563604
Hali! 
(Mvvm terv minta) Wpf ben kirajzoltatom Canvasra a kis téglalapjaim, és ezeknek a kis téglalapoknak szeretnék eseményt létrehozni, de nem fut le a kockaMousEnter  parancsom. Esetleg CommandParaméterben átkellene neki még neki paramétert?

<ItemsControl ItemsSource="{Binding rects, Mode=TwoWay}" Margin="10,33,362,316"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas Width="120" Height="120" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style TargetType="ContentPresenter"> <Setter Property="Canvas.Left" Value="{Binding Left}"/> <Setter Property="Canvas.Top" Value="{Binding Top}"/> </Style> </ItemsControl.ItemContainerStyle> <ItemsControl.ItemTemplate> <DataTemplate> <Rectangle Width="{Binding Width}" Height="{Binding Height}" Fill="{Binding Color}"> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseLeave"> <i:InvokeCommandAction Command="{Binding kockaMouseEnter}" /> </i:EventTrigger> </i:Interaction.Triggers> </Rectangle> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl>
Mutasd a teljes hozzászólást!
A kód kicsit egybefolyik, de az látszik így is, hogy a Rect osztályod az, amiről beszéltem, tehát a kockaMouseEnter nevű DelegateCommand-od ott próbál lefutni.

Nem jelzi ki az output ablakod, hogy nem találja ezt a property-t? Valami ilyesminek kéne megjelennie:

System.Windows.Data Error: 40 : BindingExpression path error: 'kockaMouseEnter ' property not found on 'object'...

A megoldás az, hogy jelzed, hogy a szülő objektum DataContext-jén keresed ezt a property-t, valahogy így:

<i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.kockaMouseEnter}" />
Mutasd a teljes hozzászólást!

  • Helló!

    A XAML szerintem jó. Nem raktad be a ViewModel kódjaid, így csak találgatni lehet, mi lehet a gond. Néhány tipp:

    Futtatás közben az Output ablakban megjelenik, ha az adatkötés során nem sikerült megtalálni a hivatkozott property-t. Egyértelműen sikerül azt megtalálnia, nincs hiba?

    Alapesetben ha DataTemplate-ben definiálsz parancsot, az a DataTemplate-et használó objektum property-jén próbál lefutni.

    Ez az az osztálynév, ami a kódodból nem derül ki. A rects nevű ObservableCollection típusa ez, ennek van a Width, Height és Color property-je. Na ott próbál lefutni a kockaMouseEnter parancsod. Ott implementáltad az ICommand-ot?

    (Megjegyezném, hogy a MouseLeave eseményhez kötöd a kockaMouseEnter parancsot. Ennek nincs köze a problémához, csak következetlen.)
    Mutasd a teljes hozzászólást!
  • Szia! másolom a kódot:

    /// <summary> /// konstruktor /// </summary> public NezetModel() { rects = new ObservableCollection<Rect>(); kockaMouseEnter = new DelegateCommand(param => KockaMouseEnter()); } public DelegateCommand kockaMouseEnter { get; private set; } private string _szoveg; public string Szoveg { get { return _szoveg; } set { _szoveg = value; OnPropertyChanged(); } } int kockakVizszintesen = 4; int kockakFuggolegesen = 5; int tavolsagKockakKozott = 13; SolidColorBrush kijelolve = Brushes.Yellow; SolidColorBrush alapSzin = Brushes.Black; private ObservableCollection<Rect> _rects; public ObservableCollection<Rect> rects { get { return _rects; } set { _rects = value; } } public class Rect { public int Width { get; set; } public int Height { get; set; } public int Left { get; set; } public int Top { get; set; } public SolidColorBrush Color { get; set; } } /// <summary> /// Feltoltjuk a kollekciot a kokckakkal /// </summary> protected void feltolt() { int oldal = 0; int fent = 0; for (int j = 0; j < kockakFuggolegesen; j++) { for (int i = 0; i < kockakVizszintesen; i++) { rects.Add(new Rect() { Width = 10, Height = 10, Left = oldal, Top = fent, Color = alapSzin }); oldal += tavolsagKockakKozott; } oldal = 0; fent += tavolsagKockakKozott; } } public void KockaMouseEnter() { Szoveg = "lefutott"; //ideiglenesen egy Szöveg nevü label jelezné ha lefutna az ide írt kód OnPropertyChanged("rects"); } xml : <Label Content="{Binding Szoveg}" HorizontalAlignment="Left" Margin="86,422,0,0" VerticalAlignment ="Top" /> Itt most két sort beletettem, komment jellel jelzem: public class Rect { .... public SolidColorBrush Color { get; set; } public DelegateCommand command { get; set; }///////// } protected void feltolt() { .... Color = alapSzin, command = kockaMouseEnter ///////////// .... }
    Igazábol majd azt szeretném, hogy amelyik kis kockán állok az egérrel, és amikor levan nyomva a bal egér, akkor megváltozzon a kocka szine, ha jobbal, akkor pedig alapállapotra vissza váltson.
    Majd pedig a kockák szine alapján előállítok egy double mátrixot, amit majd kezel a neurális hálozat:
    Ennek a kódja mvvm nélkül ami a RajzTabla nevü canvas elemeit dolgozza fel:

    /// <summary> /// a kockák szine alapján állítjuk be a double[] értékeit /// </summary> /// <returns></returns> protected double[,] sorozatMatrixEloallitasa() { double[,] lista = new double[1,kockakFuggolegesen * kockakVizszintesen]; for (int i = 0; i < lista.Length; i++) { if ((RajzTabla.Children[i] as Rectangle).Fill == kijelolve) { lista[0,i] = 1; } else lista[0,i] = 0; } return lista; }
    Mutasd a teljes hozzászólást!
  • A kód kicsit egybefolyik, de az látszik így is, hogy a Rect osztályod az, amiről beszéltem, tehát a kockaMouseEnter nevű DelegateCommand-od ott próbál lefutni.

    Nem jelzi ki az output ablakod, hogy nem találja ezt a property-t? Valami ilyesminek kéne megjelennie:

    System.Windows.Data Error: 40 : BindingExpression path error: 'kockaMouseEnter ' property not found on 'object'...

    A megoldás az, hogy jelzed, hogy a szülő objektum DataContext-jén keresed ezt a property-t, valahogy így:

    <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.kockaMouseEnter}" />
    Mutasd a teljes hozzászólást!
  • Köszi a megoldást, működik :)
    Mutasd a teljes hozzászólást!
  • Abban tudnál még segíteni, hogy ha CommandParaméterrel kiakarom egészíteni a kódot, ugy hogy arra a kockára hivatkozzon, amin végrehajtódik az esemény pl mouseEnter.

    <i:InvokeCommandAction Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=DataContext.kockaMouseEnter}" CommandParameter="{Binding RelativeSource={RelativeSource Self}}" /> kockaMouseEnter = new DelegateCommand(param => KockaMouseEnter(param)); public void KockaMouseEnter(Object param) { if (param == null) { return; } if (param is Rectangle) { ((Rectangle)param).Fill = kijelolve; } OnPropertyChanged("rects"); }
    Mutasd a teljes hozzászólást!
  • Hát amennyiben színezgetni szeretnéd, lehet, hogy jobban járnál - programtervezési szempontból -, ha egyszerűen a Rect osztályban definiálnád a színezési parancsot (és az eredeti XAML-t használod). Így mindig az aktuális Rect osztályon fog lefutni a parancs, mindenféle egyéb paraméter nélkül.

    Egyébként itt egy leírás, hogyan lehet DelegateCommand segítségével paramétereket átadni.

    (Tipp: DelegateCommand<Rect>...)
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd