Правильная реализация MVVM динамически сгенерированного пользовательского контроля - PullRequest
0 голосов
/ 15 января 2020

Мой сценарий: у меня есть пользовательский контроль, состоящий из comboBox и TextBox. ComboBox должен содержать числа, содержащиеся в ObservableCollection.

Задача: числа в ObservableCollection представляют пути к главам книги; поэтому каждая глава уникальна. Значение: если у меня есть главы 1 - 5, то первая комбинация userControl должна показывать все главы 1-5 (тогда как одна из них выбрана случайным образом), вторая комбинация userControl содержит все главы, но не ту, которая была выбрана в предыдущей комбинации, и так далее. TextBox предназначен для аннотаций к главам.

Чего я достиг на данный момент: у меня нет модели; просто основная viewModel (ItemsViewModel в моем случае) и viewModel для моего userControl (PathViewModel). Затем есть представление главного окна.

Проблема: в моем главном окне я могу создать несколько динамически создаваемых пользовательских элементов управления. UserControl TextBox в настоящее время связан с текстовым свойством, в то время как индекс comboBox связан с другим свойством. Но я не знаю: - как получить доступ к индексу, выбранному элементу / значению конкретно userControls - как реагировать на изменение элемента / списка comboBox

Вот мой код: userControl

<UserControl>  <StackPanel Orientation="Horizontal">
    <ComboBox x:Name="combo" Margin="10" MinWidth="60" VerticalAlignment="Center" ItemsSource="{Binding AvailableNumbers}" SelectedIndex="{Binding TheIndex}" />
    <TextBox Margin="10" MinWidth="120" Text="{Binding TheText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>

Главное окно

<Window>...<Window.DataContext>
    <local:ItemsViewModel/>
</Window.DataContext>

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <StackPanel x:Name="HostPanel">

        <ItemsControl ItemsSource="{Binding PathViewModels}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <local:PathControl/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>

    </StackPanel>
    <StackPanel Grid.Column="1">
    <Button Command="{Binding UCCreationCommand}" Content="Add User Control" Margin="10"/>
    <Button Command="{Binding UCDeletionCommand}" CommandParameter="" Content="Delete User Control" Margin="10"/>
    <Button Command="{Binding ReadoutCommand}" Content="Show ITEMS" Margin="10"/>
    </StackPanel>

</Grid></Window>

Моя основная ViewModel (называемая ItemsViewModel)

public class ItemsViewModel : NotifyPropertyChangedBase    
{private int _aNumber;
 public int ANumber
{
get { return _aNumber; }
set { _aNumber = value;
OnPropertyChanged(ref _aNumber, value);
}
 }
 public ObservableCollection<PathViewModel> PathViewModels { get; set; } = new 
ObservableCollection<PathViewModel>();

    public ObservableCollection<int> AllNumbers { get; set; } = new ObservableCollection<int>();

    public ItemsViewModel()
    {
        UCCreationCommand = new CommandDelegateBase(UCCreationExecute, UCCreationCanExecute);
        UCDeletionCommand = new CommandDelegateBase(UCDeletionExecute, UCDeletionCanExecute);
        ReadoutCommand = new CommandDelegateBase(ReadoutExecute, ReadoutCanExecute);

        AllNumbers.Add(1);
        AllNumbers.Add(2);
        AllNumbers.Add(3);
        AllNumbers.Add(4);
        AllNumbers.Add(5);
    }

    private bool ReadoutCanExecute(object paramerter)
    {
        if (PathViewModels.Count > 0)
        {
            return true;
        }

        return false;
    }

    private void ReadoutExecute(object parameter)
    {
        //just for testing
    }

    public ICommand UCCreationCommand { get; set; }
    public ICommand UCDeletionCommand { get; set; }
    public ICommand ReadoutCommand { get; set; }


    private bool UCCreationCanExecute(object paramerter)
    {
        if (PathViewModels.Count < 8)
        {
            return true;
        }
        else
        {
            return false;
        }
    }

    private void UCCreationExecute(object parameter)
    {
        PathViewModel p = new PathViewModel();

        foreach (int i in AllNumbers)
        {
            p.AvailableNumbers.Add(i);
        }

        int rndIndex = 0;

        Random rnd = new Random();

        //creates a random chapter index
        rndIndex = rnd.Next(0, p.AvailableNumbers.Count);

        //just explicit for debugging reasons
        p.TheIndex = rndIndex;

AllNumbers.RemoveAt ( rndIndex);

        PathViewModels.Add(p);
    }

    private bool UCDeletionCanExecute(object paramerter)
    {
        if (PathViewModels.Count != 0)
        {
            return true;
        }
        else
        {
            return false;
        }

    }

    private void UCDeletionExecute(object parameter)
    {
        PathViewModel p = new PathViewModel();
        int delIndex = PathViewModels.Count - 1;

        p = PathViewModels[delIndex];

        AllNumbers.Add((int)p.TheValue+1);


        PathViewModels.Remove(p);
    }     

}

И, наконец, моя UserControl ViewModel:

public class PathViewModel : NotifyPropertyChangedBase
{

    public ObservableCollection<int> AvailableNumbers { get; set; } = new ObservableCollection<int>();

    private int _theIndex;

    public int TheIndex
    {
        get { return _theIndex; }
        set
        {
            _theIndex = value;
            OnPropertyChanged(ref _theIndex, value);
        }
    }

    private int _theValue;

    public int TheValue
    {
        get { return _theValue; }
        set
        {
            _theValue = value;
            OnPropertyChanged(ref _theValue, value);
        }
    }

    private string _theText;

    public string TheText
    {
        get { return _theText; }
        set
        {
            _theText = value;
            OnPropertyChanged(ref _theText, value);
        }
    }

    public PathViewModel()
    {

    }       

}

Любые подсказки о том, как go отсюда, будут высоко оценены.

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