Двухстороннее связывание комбинированного списка с простым массивом строк - PullRequest
3 голосов
/ 16 сентября 2010

У меня есть простой класс, который предоставляет коды состояния, такие как:

public class StateProvider
{
    static string[] _codes = new string[]
    {
        "AL",
        "AK",
        ...
    };

    public string[] GetAll()
    {
        return _codes;
    }
}

Мой класс модели, который поддерживает представление, выглядит примерно так:

public class ProjectModel : ChangeNotifier
{
    StateProvider _states = new StateProvider();

    public ProjectModel()
    {
        Project = LoadProject();
    }

    ProjectEntity _project;
    public ProjectEntity Project
    {
        get { return _project; }

        set
        {
            _project = value;
            FirePropertyChanged("Project");
        }
    }

    public string[] States { get { return _states.GetAll(); } }
}

И мой ComboBox XAMLвыглядит следующим образом:

<ComboBox SelectedValue="{Binding Project.State, Mode=TwoWay}" SelectedValuePath="{Binding RelativeSource={RelativeSource Self}}" ItemsSource="{Binding States}" />

Привязка работает от пользовательского интерфейса к объекту - если я выбираю состояние из комбо, то значение передается объекту проекта, и я могу сохранить его.Однако, если я завершаю работу и перезагружаюсь, значение кода состояния не привязывается от объекта к пользовательскому интерфейсу, и в комбинированном списке ничего не отображается.Затем, конечно, последующее сохранение обнуляет значение состояния объекта.

Я хочу, чтобы это было очень просто, поскольку я хочу отображать коды состояния и сохранять коды состояния (я не хочу отображать полное имя состояния).Так что я не хочу возиться с созданием класса State, который имеет свойства Code и FullName, и избегать необходимости использовать свойства SelectedValuePath и DisplayMemberPath комбинированного списка.

Редактировать: добавлен в код, как ProjectModelизменить уведомление.Обратите внимание, что класс ProjectEntity делает это тоже.Поверь мне это работает.Я пропустил это, потому что он также наследуется от базового класса Entity, который изменяет уведомление посредством отражения.Двухстороннее связывание работает на всем, кроме комбинированного списка.

Ответы [ 3 ]

1 голос
/ 01 октября 2010

Ого, кто бы мог подумать, что это сводится к следующему:

<ComboBox ItemsSource="{Binding States}" SelectedValue="{Binding Project.State, Mode=TwoWay}" />

Оказалось, что это был порядок, в котором я поместил атрибуты в XAML.Привязка SelectedValue происходила до привязки ItemsSource, и поэтому в выпадающем списке не было элементов, когда было привязано SelectedValue.

Вау, это просто кажется очень плохой вещью.

1 голос
/ 17 сентября 2010

Вы должны по крайней мере реализовать IPropertyNotifyChanged в своем классе ProjectModel

public class ProjectModel : INotifyPropertyChanged
{
        public event PropertyChangedEventHandler PropertyChanged;

и реализовать свойство Project, как показано ниже, для привязки к работе, отличной от 1-way-1-time.

public ProjectEntity Project
{
    get { return (ProjectEntity)GetValue(ProjectProperty); }
    set { SetValue(ProjectProperty, value); }
}

// Using a DependencyProperty as the backing store for Project.  
// This enables animation, styling, binding, etc...
public static readonly DependencyProperty ProjectProperty =
    DependencyProperty.Register("Project",
                                typeof(ProjectEntity),
                                typeof(ProjectModel),
                                new PropertyMetadata(null,
                                    new PropertyChangedCallback(OnProjectChanged)));

static void OnProjectChanged(object sender, DependencyPropertyChangedEventArgs args)
{
    // If you need to handle changes
}
0 голосов
/ 01 октября 2010

Измените свой класс ProjectModel следующим образом:

public class ProjectModel : ChangeNotifier
{
    StateProvider _states = new StateProvider();

    public ProjectModel()
    {
        Project = LoadProject();

        States = new ObservableCollection<string>(_states.GetAll());
    }

    ProjectEntity _project;
    public ProjectEntity Project
    {
        get { return _project; }

        set
        {
            _project = value;
            FirePropertyChanged("Project");
        }
    }

    public ObservableCollection<string> States { get; set; }
}

Также убедитесь, что ProjectEntity также реализует INotifyPropertyChanged.

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