MVVM установка значений по умолчанию - PullRequest
0 голосов
/ 03 августа 2010

Я уверен, что это довольно распространенный сценарий, и я хотел бы знать, как разработчики MVVM справляются с этим.

У меня есть ViewModel, который создается по требованию и сохраняется до тех пор, пока он не будет явно удаленПользователь.Соответствующий вид загружается в пользовательский интерфейс по требованию.Представление может быть выгружено, и его ViewModel может все еще существовать в приложении.

В моем сценарии у меня есть ListBox предустановленных цветов в представлении (путем установки его ItemsSource в ObservableCollection, определенный в Xaml для SolidColorBrush).

Я связал свойство SelectedItem объекта ListBox со свойством в ViewModel, чтобы при повторной загрузке представления SelectedItem правильно отображал последний выбранный элемент в ListBox, а также когда пользователь выбирает другой цвет.виртуальная машина будет обрабатывать изменения.

Мой вопрос: как установить значение по умолчанию, скажем, третий элемент в ObservableCollection SolidColorBrush для ViewModel при первой загрузке представления?

Ответы [ 5 ]

2 голосов
/ 19 марта 2013

Обычно я устанавливаю значения по умолчанию в конструкторе, если для загрузки значений по умолчанию может потребоваться некоторое время, и в этом случае я установлю вызов метода, чтобы установить его в получателе для свойства bound.

Причиной этого является упрощение обслуживания. Если я ищу, где установить значение по умолчанию, чтобы я мог просмотреть или изменить его, первое, что я проверяю, - это конструктор. Его легче найти, чем прокручивать свойства, и, как известно, он содержит логику инициализации.

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

Для свойств, загрузка которых может занять больше времени, я использую метод, который вызывается в получателе по той же причине. Как правило, все мои свойства и их методы получения / установки скрыты в регионе, и мне гораздо легче найти метод с именем LoadColors() в моем классе, чем найти свойства Colors в огромном списке свойств, которые у меня есть. Кроме того, его можно использовать повторно, поэтому, если мне нужно что-то сделать, например сбросить значение, это легко сделать без повторения моего кода.

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

        return _colors;
    }
    set { ... }
}

void LoadColors()
{
    // Initialization logic here
}

Вы также можете установить значение по умолчанию в своем XAML, используя FallbackValue привязки, однако это обычно имеет смысл, только когда существует вероятность того, что привязка 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 голос
/ 19 марта 2013

Первое чтение Хосе Ответьте, если ваш ответ на его вопрос будет " да ", попробуйте это

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 по умолчанию устанавливается SelectedIndex, который ограничен для OneTime режима до mySelectedIndex.Я также покажу здесь, как вы могли бы получить это IntoViewя как это кому-нибудь поможет.

1 голос
/ 03 августа 2010

Я считаю, что ваша ошибка в вашей реализации.Причиной наличия MVVM является разделение интересов.Это делает ваш взгляд просто реализацией, которую можно переключать или обновлять, если / когда возникнет такая необходимость.Как только вы начинаете размещать в своем представлении материал, который является частью логики приложения, вы идете по пути головной боли, связанной с обслуживанием, и тогда может быстро возникнуть код спагетти.

Некоторые люди говорят: «Не ставьтелюбой код на ваш взгляд ", я согласен в 99% случаев.Я говорю: «Не ставьте домен / приложение / бизнес-логику на ваш взгляд».

Всякий раз, когда вы пытаетесь поместить какой-то код в ваше представление, спрашивайте себя: «Если я переключусь с WPF на другую среду, будет ли мое приложение работать?»Если ответ «нет», измените вашу ViewModel, чтобы включить в нее то, что вы пытались добавить в ваше представление.

0 голосов
/ 03 августа 2010

Если свойство, привязанное к 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 .
0 голосов
/ 03 августа 2010

обычно В MVVM ваша ObservableCollection SolidBrushColor должна быть определена как свойство в ViewModal.и это свойство должно быть привязано к вашему ListBox.Теперь, чтобы установить значение по умолчанию, вы можете использовать его в конструкторе ViewModal

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...