MVVM设置默认值

时间:2010-08-03 07:22:50

标签: c# wpf mvvm

我确信这是一个非常常见的场景,我想知道MVVM开发人员如何解决这个问题。

我有一个按需实例化的ViewModel,并持续存在,直到用户明确删除。它根据需要将相应的View加载到UI上。 View可以卸载,它的ViewModel可能仍然存在于应用程序中。

在我的场景中,我在视图中有一个预设颜色的ListBox(通过将其ItemsSource设置为Xaml定义的SolidColorBrush的ObservableCollection)。

我将ListBox的SelectedItem属性绑定到ViewModel中的属性,以便在再次加载View时,SelectedItem正确显示ListBox中最后选择的项目,并且当用户选择不同的颜色时,VM将处理变化。

我的问题是,你如何设置默认值,在首次加载View时,将SolidColorBrush的ObservableCollection中的第三项说成ViewModel?

5 个答案:

答案 0 :(得分:2)

通常我在构造函数中设置默认值,除非默认值可能需要一些时间才能加载,在这种情况下,我将调用一个方法在绑定属性的getter中设置它。

这样做的原因是为了简化维护。如果我正在寻找我设置默认值的位置,以便我可以查看或更改它,我检查的第一个位置是构造函数。它比滚动属性更容易找到,并且已知包含初始化逻辑。

MyViewModel()
{
    // Set defaults 
    SelectedColor = Brushes.Red;
}

对于可能需要更长时间加载的属性,我使用在getter中调用的方法也是出于同样的原因。通常我的所有属性及其getter / setter都隐藏在一个区域中,我发现在我的类中找到一个名为LoadColors()的方法比在巨大的属性列表中找到Colors属性要容易得多有。此外,它是可重用的,所以如果我需要执行重置值这样的操作,那么在不重复代码的情况下这样做很容易。

ObservableCollection<SolidColorBrush> Colors
{
    get
    {
        if (_colors == null)
            LoadColors();

        return _colors;
    }
    set { ... }
}

void LoadColors()
{
    // Initialization logic here
}

您还可以使用绑定的FallbackValue在XAML中设置默认值,但是这通常只有在评估绑定时绑定的DataContext不存在时才有意义

<!-- You may have to look up the exact syntax for Brushes.Red -->
<ListBox SelectedItem="{Binding SelectedColor, FallbackValue=Red}" />

最后但并非最不重要的是,您始终可以使用代码隐藏视图来执行特定于视图的逻辑,就像您的示例一样。例如,

void ComboBox_Loaded(object obj, EventArgs e)
{
    if (MyComboBox.SelectedIndex == -1)
        MyComboBox.SelectedIndex = 2;
}

答案 1 :(得分:1)

我相信您的错误在于您的实施。拥有MVVM的原因是要“分离关注点”。这使得您的视图只是一个实现,可以在需要时进行切换或更新。一旦你开始在你的视图中放入属于应用程序逻辑的东西,你就会走上维护头痛的道路,然后意大利面条代码可以很快发生。

有些人说,“不要在你的视图中放任何代码”,我同意99%的时间。我说“不要在你的视图中放置任何域/应用程序/业务逻辑。”

每当你试图将一些代码放入你的视图中时问问自己“如果我从WPF切换到另一个框架,我的应用程序是否仍然有效?”如果答案为否,则修改您的ViewModel以合并您尝试放在视图中的内容。

答案 2 :(得分:1)

首先阅读Jose如果他的问题的回答是“”,请回答

XAML

<Window x:Class="icube.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Grid>
        <ListBox Name="myLB" Margin="0,0,445,291"
                 SelectedItem="{Binding mySelectedItem, UpdateSourceTrigger=PropertyChanged}" 
                 SelectedIndex="{Binding mySelectedIndex,Mode=OneTime}" >
            <ListBox.ItemTemplate>
                <!-- or what ever yourTemplate will be-->
                <DataTemplate DataType="{x:Type SolidColorBrush}">
                    <Rectangle Width="20" Height="20" Fill="{Binding}"/>
                </DataTemplate>
            </ListBox.ItemTemplate>          
        </ListBox>
    </Grid>
</Window>

代码隐藏

using System.Windows;
using System.Windows.Media;
using System.Collections.ObjectModel;

namespace icube
{
    /// <summary>
    /// Interaktionslogik für MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            var obcoll = new ObservableCollection<SolidColorBrush>();

            obcoll.Add(Brushes.Red);
            obcoll.Add(Brushes.Green);
            obcoll.Add(Brushes.Yellow);
            obcoll.Add(Brushes.Blue);
            obcoll.Add(Brushes.Orange);

            myLB.ItemsSource = obcoll;

            DataContext = new myClass();
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            //importent if you want to see your selected Element
            myLB.ScrollIntoView(myLB.SelectedItem);
        }
    }
}

myClass的

public class myClass
{
    private SolidColorBrush _mySelectedItem = new SolidColorBrush();
    public SolidColorBrush mySelectedItem
    {
        get { return _mySelectedItem; }
        set { _mySelectedItem = value; }
    }

    public int mySelectedIndex
    {
        get { return 4; }
    }
}

摘要

您可以看到SelectedItem设置的默认SelectedIndexOneTime模式限制为mySelectedIndex。我还在这里展示了如何让它进入IntoView
我将如何帮助某人。

答案 3 :(得分:0)

通常在MVVM中,应将ObBableCollection的SolidBrushColor定义为ViewModal中的属性。并且此属性应绑定到ListBox。现在,要设置默认值,您可以在ViewModal的构造函数

中使用它

答案 4 :(得分:0)

如果绑定到SelectedItem的属性被声明为依赖项属性,那么您可以将依赖项属性的默认值设置为您想要的任何值。

 public static readonly DependencyProperty SelectedColorProperty
   = DependencyProperty.Register("SelectedColor", typeof(SolidBrushColor ), 
                                                typeof(<yourviewmodel>),
                                                new UIPropertyMetadata(GetDefaultColor()));

  Where GetDefaultColor() is a static method in your ViewModel, 
  which will return the required color from your ObservableCollection .