Note that there are some explanatory texts on larger screens.

plurals
  1. POMVVM Listbox Update Content Maintain Selected Item Silverlight
    text
    copied!<p>I've been reading a lot about MVVM (using Laurent Bugnion's library in specific) and I'm constantly struggling to determine how to do things in MVVM that were otherwise easy with code behind.</p> <p>Here's just one example where I suspect I'm doing things the hard way. If anyone has the time to read all this, perhaps they can comment on the sanity of my approach. :)</p> <p>I have a list box bound to a ViewModel like so:</p> <pre><code>&lt;ListBox x:Name="lstFruitBasketLeft" ItemsSource="{Binding FruitBasket}" SelectedItem="{Binding SelectedFruit, Mode=TwoWay}" Width="150"&gt; &lt;ListBox.ItemTemplate&gt; &lt;DataTemplate&gt; &lt;StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="2"&gt; &lt;TextBlock Text="{Binding Name}" /&gt; &lt;TextBlock Text=":" /&gt; &lt;TextBlock Text="{Binding Quantity}" /&gt; &lt;/StackPanel&gt; &lt;/DataTemplate&gt; &lt;/ListBox.ItemTemplate&gt; </code></pre> <p></p> <p>The ItemSource is an ObservableCollection of Fruit objects:</p> <pre><code>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; } } </code></pre> <p>It is defined in the ViewModel as:</p> <pre><code>// Property FruitBasket public const string FruitBasketPropertyName = "FruitBasket"; private ObservableCollection&lt;Fruit&gt; _fruitBasket = null; public ObservableCollection&lt;Fruit&gt; FruitBasket { get { return _fruitBasket; } set { if (_fruitBasket == value) return; _fruitBasket = value; // Update bindings, no broadcast RaisePropertyChanged(FruitBasketPropertyName); } } </code></pre> <p>The bound SelectedItem property is as such:</p> <pre><code>//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); } } </code></pre> <p>Then, the list is populated on the construction of the ViewModel.</p> <p>Now, I add a RelayCommand to a button on the presentation page that executes a method which increments the quantity of the selected item. Note that I am not using the parameter yet, but "Bob" is a placeholder for some changes for later.</p> <pre><code>&lt;Button x:Name="butMore" Content="More!" HorizontalAlignment="Right" Height="25" Width="75" Margin="4"&gt; &lt;i:Interaction.Triggers&gt; &lt;i:EventTrigger EventName="Click"&gt; &lt;cmd:EventToCommand Command="{Binding addMoreCommand}" CommandParameter="Bob" /&gt; &lt;/i:EventTrigger&gt; &lt;/i:Interaction.Triggers&gt; &lt;/Button&gt; </code></pre> <p>Here's the code for the command:</p> <pre><code>// Property addMoreCommand public RelayCommand addMoreCommand { get; private set; } </code></pre> <p>...</p> <pre><code> //Init relays (this is in the constructor) addMoreCommand = new RelayCommand(AddFruit, CanExecute); </code></pre> <p>...</p> <pre><code>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&lt;Fruit&gt;(FruitBasket); //Reselect SelectedFruit = oldSelectedItem; } public bool CanExecute() { return true; //for now } </code></pre> <p>Now this does work, but I have some problems with it: </p> <p>First, I feel like there are a lot of conditions that have to come together for this to work and I wonder if I'll get so lucky trying to move some Telerik Drag and Drop code into MVVM. </p> <p>Second, it seems like a pretty poor performance approach to recreate the list like that. </p> <p>Lastly, it seems like this would be easier in code behind (though I'm not 100% certain I still won't have to rebuild that list).</p> <p>Does anyone have any thoughts on my approach or perhaps even... suggestions to make things easier? Am I just missing something obvious here?</p> <p>Thanks</p> <p>-Driodilate :]</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload