gpt4 book ai didi

silverlight - MVVM 列表框更新内容维护所选项目 Silverlight

转载 作者:行者123 更新时间:2023-12-04 15:48:28 28 4
gpt4 key购买 nike

我一直在阅读很多关于 MVVM 的文章(特别是使用 Laurent Bugnion 的库),并且我一直在努力确定如何在 MVVM 中做一些事情,否则这些事情在后面的代码中很容易。

这只是我怀疑我正在以艰难的方式做事的一个例子。如果有人有时间阅读所有这些,也许他们可以评论我的方法的理智。 :)

我有一个绑定(bind)到 ViewModel 的列表框,如下所示:

<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 是 Fruit 对象的 ObservableCollection:
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;
}
}

它在 ViewModel 中定义为:
// 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);
}
}

绑定(bind)的 SelectedItem 属性如下:
//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);
}
}

然后,在 ViewModel 的构造上填充列表。

现在,我将 RelayCommand 添加到演示页面上的按钮,该按钮执行增加所选项目数量的方法。请注意,我尚未使用该参数,但“Bob”是稍后进行某些更改的占位符。
<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>

这是命令的代码:
// 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
}

现在这确实有效,但我有一些问题:

首先,我觉得有很多条件必须结合在一起才能工作,我想知道我是否会很幸运尝试将一些 Telerik 拖放代码移动到 MVVM 中。

其次,重新创建这样的列表似乎是一种性能很差的方法。

最后,这似乎在后面的代码中会更容易(尽管我不是 100% 确定我仍然不必重建该列表)。

有没有人对我的方法有任何想法,或者甚至......建议让事情变得更容易?我只是在这里遗漏了一些明显的东西吗?

谢谢

-Driodilate :]

最佳答案

莫尔基,

如果您必须刷新 ObservableCollection,则会出现问题.通常,您不需要它,因为 ObservableCollection将通知项目更改。

永远不要这样做:

FruitBasket = new ObservableCollection<Fruit>(FruitBasket);

您的 public ObservableCollection<Fruit> FruitBasket应该有 没有公共(public)二传手 ,它应该是只读的。只需 AddRemove列表中的项目。

如果你想处理多个选择,你可能需要一个扩展的 CollectionView哪位能解决这个问题,获取更多提示 here .

我希望这会有所帮助,即使我可能没有回答所有问题:)

编辑:
好吧,我想我弄错了一些东西。现在我想我完全理解你想要完成的事情。你是 不是 当您的属性(property)发生变化时会收到通知,对吗?好吧,出于这个原因,我们在我们的一个项目中调整了“ BindableLinq”,您可以在 Silverlight 中毫无问题地编译它。 (有类似的解决方案可用,称为 Continuous LinqObtics,请自行选择)。

使用 BindableLinq ,您可以转换您的 ObservableCollectionBindableCollection使用一种扩展方法。 BindableCollection然后将正确反射(reflect)所有更改。试试看。

EDIT2:
实现 正确的 ViewModel,请考虑以下更改。

1) Fruit是你的 型号 .由于它没有实现 INotifyPropertyChanged ,它不会传播任何更改。创建 FruitViewModel ,嵌入您的 Fruit建模和调用 RaisePropertyChanged对于每个属性 setter 。

2) 更改您的 FruitBasket成为 ObservableCollectionFruitViewModel .慢慢地它开始变得有意义:)

3) SelectedFruit必须是 FruitViewModel也是。现在它更有意义了。

4) 现在它已经对我有用了,即使没有 BindableLinq .你有什么成功吗?

高温高压

最好的祝福,
托马斯

关于silverlight - MVVM 列表框更新内容维护所选项目 Silverlight,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4218812/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com