Wiele czytałem o MVVM (używając biblioteki Laurenta Bugniona w szczególności) i ciągle walczę o to, aby ustalić, jak robić rzeczy w MVVM, które w innym przypadku byłyby łatwe z kodem.Zawartość Aktualizacji Listbox MVVM Utrzymanie Wybranego Elementu Silverlight
Oto tylko jeden przykład, w którym podejrzewam, że robię rzeczy w trudny sposób. Jeśli ktokolwiek ma czas na przeczytanie tego wszystkiego, może może wypowiedzieć się na temat zdrowego rozsądku mojego podejścia. :)
Mam pole listy związany z ViewModel tak:
<ListBox x:Name="lstFruitBasketLeft" ItemsSource="{Binding FruitBasket}"
SelectedItem="{Binding SelectedFruit, Mode=TwoWay}" Width="150">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" VerticalAlignment="Center"
HorizontalAlignment="Left" Margin="2">
<TextBlock Text="{Binding Name}" />
<TextBlock Text=":" />
<TextBlock Text="{Binding Quantity}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
ItemSource jest ObservableCollection obiektów owocowe:
public class Fruit
{
public string Name { get; set; }
public int Quantity { get; set; }
public Fruit() { }
public Fruit(string name, int quantity)
{
this.Name = name;
this.Quantity = quantity;
}
}
To jest zdefiniowane w ViewModel as:
// Property FruitBasket
public const string FruitBasketPropertyName = "FruitBasket";
private ObservableCollection<Fruit> _fruitBasket = null;
public ObservableCollection<Fruit> FruitBasket
{
get { return _fruitBasket; }
set
{
if (_fruitBasket == value)
return;
_fruitBasket = value;
// Update bindings, no broadcast
RaisePropertyChanged(FruitBasketPropertyName);
}
}
Związana właściwość SelectedItem jest jako takie:
//Property SelectedFruit
public const string SelectedFruitPropertyName = "SelectedFruit";
private Fruit _selectedFruit = null;
public Fruit SelectedFruit
{
get { return _selectedFruit; }
set
{
if (_selectedFruit == value)
return;
var oldValue = _selectedFruit;
_selectedFruit = value;
// Update bindings, no broadcast
RaisePropertyChanged(SelectedFruitPropertyName);
}
}
Następnie lista jest wypełniana na budowę ViewModel.
Teraz dodaję funkcję RelayCommand do przycisku na stronie prezentacji, który wykonuje metodę zwiększania ilości wybranego elementu. Zauważ, że nie używam jeszcze tego parametru, ale "Bob" jest symbolem zastępczym niektórych zmian na później.
<Button x:Name="butMore" Content="More!" HorizontalAlignment="Right" Height="25" Width="75" Margin="4">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cmd:EventToCommand
Command="{Binding addMoreCommand}"
CommandParameter="Bob" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Oto kod za pomocą polecenia:
// Property addMoreCommand
public RelayCommand addMoreCommand
{
get;
private set;
}
...
//Init relays (this is in the constructor)
addMoreCommand = new RelayCommand(AddFruit, CanExecute);
...
public void AddFruit()
{
//Increment the fruit
SelectedFruit.Quantity++;
//Save the previous selected item
Fruit oldSelectedItem = SelectedFruit;
//We have to have a new list in order to get the list box to refresh
FruitBasket = new ObservableCollection<Fruit>(FruitBasket);
//Reselect
SelectedFruit = oldSelectedItem;
}
public bool CanExecute()
{
return true; //for now
}
Teraz to działa, ale mam pewne problemy z tym:
Po pierwsze, czuję, że istnieje wiele warunków, które muszą się ze sobą połączyć, aby zadziałało i zastanawiam się, czy będę miał tyle szczęścia, próbując przenieść kod telelizujący i przeciągnij Telerik do MVVM.
Po drugie, wygląda na to, że do odtworzenia takiej listy wystarcza bardzo słabe podejście do wydajności.
Wreszcie, wydaje się, że będzie łatwiej w kodzie za sobą (chociaż nie jestem w 100% pewny, że nadal nie będę musiał odbudowywać tej listy).
Czy ktoś ma jakieś przemyślenia na temat mojego podejścia, a może nawet ... sugestie, aby ułatwić sobie pracę? Czy właśnie tu brakuje czegoś oczywistego?
Dzięki
-Driodilate:]
Dobrze, że nie pomaga, ale pozostawia mnie w sytuacji, nie wiedząc, jak uzyskać kontrolę związaną poprawnie zaktualizować. Pamiętaj, że nie dodaję ani nie usuwam elementów (działa to doskonale bez dodatkowego kodu). Mój problem występuje, gdy aktualizuję właściwość jednego z obiektów, który znajduje się w ObservableCollection. – maulkye
Hmmmm, chociaż mnie zmusiłeś. Mogłem po prostu usunąć wybrany element, zaktualizować go, a następnie dodać go ponownie, aby automatyczne aktualizacje działały. Chociaż nie jestem pewien, jak to wpłynie na sortowanie. – maulkye
Sprawdź moją EDYCJĘ, istnieje kolejna ścieżka, którą możesz śledzić :) – thmshd