Как привязать свойства пользовательского элемента управления к свойствам наблюдаемого объекта, содержащегося в наблюдаемой коллекции - PullRequest
0 голосов
/ 21 февраля 2020

Я использую MVVMLight и мне нужно иметь возможность программно c редактировать свойства около 12 переключателей во время инициализации View. Поскольку их так много, и я хотел бы перебрать связанные свойства, я пытаюсь использовать ObservableCollection из ObservableObject, содержащего значения, которые должны быть привязаны к свойствам кнопок переключения. Я не уверен, является ли это проблемой привязки или неправильной реализацией интерфейса INotifyPropertyChanged, унаследованного от ObservableObject.

. Вот класс, содержащий свойства, к которым я должен присоединиться sh:

public class CavitySelect : ObservableObject
{
    private string _Text;
    public string Text
    {
        get { return _Text; }
        set
        {
            _Text = value;
            RaisePropertyChanged("Text");
        }
    }
    private bool _Visible;
    public bool Visible
    {
        get { return _Visible; }
        set
        {
            _Visible = value;
            RaisePropertyChanged("Visible");
        }
    }
    private bool _Toggle;

    public bool Toggle
    {
        get { return _Toggle; }
        set
        {
            _Toggle = value;
            RaisePropertyChanged("Toggle");
        }
    }

    public CavitySelect()
    {
        Text = "";
        Visible = false;
        Toggle = false;
    }
}

Вот экземпляр моего ObservableCollection:

private ObservableCollection<CavitySelect> _CavTogglesProperties;
public ObservableCollection<CavitySelect> CavTogglesProperties
{
    get { return _CavTogglesProperties; }
    set
    {
        _CavTogglesProperties = value;
        RaisePropertyChanged("CavTogglesProperties");
    }
}

public MyViewModel()
{
    this.CavTogglesProperties = GetCavities();
}    

public ObservableCollection<CavitySelect> GetCavities()
{
    CavitySelect t11 = new CavitySelect();
    CavitySelect t12 = new CavitySelect();
    CavitySelect t13 = new CavitySelect();
    CavitySelect t14 = new CavitySelect();
    CavitySelect t15 = new CavitySelect();
    CavitySelect t16 = new CavitySelect();
    CavitySelect t26 = new CavitySelect();
    CavitySelect t21 = new CavitySelect();
    CavitySelect t22 = new CavitySelect();
    CavitySelect t23 = new CavitySelect();
    CavitySelect t24 = new CavitySelect();
    CavitySelect t25 = new CavitySelect();
    ObservableCollection<CavitySelect> temp = new ObservableCollection<CavitySelect>() {t11,t12,t13,t14,t15,t16,t21,t22,t23,t24,t25,t26};
    return temp;
}

А вот как я пытаюсь связать его:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisibilty"/>
</Window.Resources>
<Grid Background="#FFF4F4F5" Margin="8,165,8,8"  DataContext="{Binding CavTogglesProperties}">
    <ToggleButton DataContext="{Binding t11}" Content="{Binding Text}" IsChecked="{Binding Toggle}" Visibility="{Binding Visible,Converter={StaticResource BoolToVisibilty}}"/> 
</Grid>

Я подтвердил привязку класса View to ViewModel работает правильно. Я также пробовал связывать, не устанавливая сначала DataContext содержащей Grid, например:

<ToggleButton DataContext="{Binding CavTogglesProperties[t11]}" ... />

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

1 Ответ

2 голосов
/ 21 февраля 2020

Отображение коллекции предметов

Ваш вопрос не совсем понятен, но я считаю, что вы хотите показать список предметов в вашем пользовательском интерфейсе; однако, как в настоящее время реализовано, ваш XAML действительно структурирован так, чтобы отображать один элемент.

Чтобы отобразить список, вам нужно просмотреть любое из множества представлений коллекции (например, ListView * 1006). *, GridView , et c.).

Например:

<Window.Resources>
    <BooleanToVisibilityConverter x:Key="BoolToVisibilty"/>
</Window.Resources>
<Grid Background="#FFF4F4F5" Margin="8,165,8,8">
  <ListView ItemsSource="{Binding CavTogglesProperties}">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ToggleButton Content="{Binding Text}" IsChecked="{Binding Toggle}" />
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</Grid>

Чтобы отображать только определенные c элементы, необходимо отфильтровать список в ViewModel, а не привязка видимости. Если видимые элементы не изменяются во время отображения, просто отфильтруйте список при его заполнении.

Если, однако, видимости изменятся, и вы хотите, чтобы представление отражало эти изменения, посмотрите на реализацию фильтр для источника ваших предметов, как описано в этом вопросе: Как мне отфильтровать ListView в WPF? .

Поскольку вы уже используете ObservableCollection и ObservableObject, все должно автоматически обновляться.

Отображение одного элемента из коллекции

Если я неправильно прочитал ваш вопрос и вы хотите узнать, как показать один элемент из коллекции, есть несколько разных способов решения этой проблемы:

  1. Предоставить отдельный элемент как свойство в ViewModel, чтобы View не приходилось копаться в списке.
  2. Создайте конвертер , который принимает сбор и индексирование, затем вытаскивает правильный элемент.

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

Например:

private ObservableCollection<CavitySelect> _CavTogglesProperties;
public ObservableCollection<CavitySelect> CavTogglesProperties
{
    get { return _CavTogglesProperties; }
    set
    {
        _CavTogglesProperties = value;
        RaisePropertyChanged("CavTogglesProperties");
    }
}

private CavitySelect _SpecificCavToggle;
public CavitySelect SpecificCavToggle
{
    get { return _SpecificCavToggle; }
    set
    {
        _SpecificCavToggle= value;
        RaisePropertyChanged("SpecificCavToggle");
    }
}

public MyViewModel()
{
    this.CavTogglesProperties = GetCavities();
    this.SpecificCavToggle = this.CavTogglesProperties[0];
}    

public ObservableCollection<CavitySelect> GetCavities()
{
    CavitySelect t11 = new CavitySelect();
    CavitySelect t12 = new CavitySelect();
    CavitySelect t13 = new CavitySelect();
    CavitySelect t14 = new CavitySelect();
    CavitySelect t15 = new CavitySelect();
    CavitySelect t16 = new CavitySelect();
    CavitySelect t26 = new CavitySelect();
    CavitySelect t21 = new CavitySelect();
    CavitySelect t22 = new CavitySelect();
    CavitySelect t23 = new CavitySelect();
    CavitySelect t24 = new CavitySelect();
    CavitySelect t25 = new CavitySelect();
    ObservableCollection<CavitySelect> temp = new ObservableCollection<CavitySelect>() {t11,t12,t13,t14,t15,t16,t21,t22,t23,t24,t25,t26};
    return temp;
}
...