Как синхронизировать свойство в ObservableCollection в ViewModel и элемент ListBox в представлении - PullRequest
0 голосов
/ 28 мая 2019

Я хочу синхронизировать строку Dependency Свойство ViewModel UserControl и элемента ListBox в View.I попытался связать, но это не сработало.

Я хочу сделать менеджер задач, как Trello.

Приложения имеют структуру гнезда.MainWindow имеет 2 SampleContainerView.Каждый SampleContainerView имеет ListBox (ObservableCollection в ViewModel).и ListBox имеет SampleControls (это UserControl с TextBox).

Ниже приведены коды.

SampleControl.xaml

<Grid
    Background="Gray"
    >
    <TextBox
        Margin="10"
        Text="{Binding Title}"
        >
    </TextBox>
</Grid>

SampleVM.cs

public class SampleVM :DependencyObject
{
    public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title",
                            typeof(string),
                            typeof(SampleVM));

    public string Title
    {
        get { return (string)GetValue(TitleProperty); }
        set { SetValue(TitleProperty, value); }
    }

    public SampleVM(string title="init")
    {
        SetValue(TitleProperty, title);
    }
}

SampleContainer.xaml

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="2*" />
        <RowDefinition Height="1*" />
    </Grid.RowDefinitions>
    <ListBox
        ItemsSource="{Binding SampleList}"
        HorizontalContentAlignment="Stretch"
        VerticalContentAlignment="Stretch"
        Grid.Row="0"
        >
        <ListBox.ItemTemplate>
            <DataTemplate>
                <local:SampleControl></local:SampleControl>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button
        Command="{Binding AddCommand}"
        Grid.Row="1"
        Margin="10">
        add Sample...
    </Button>
</Grid>

SampleContainverVM.cs (здесь здесь не указано DelegateCommand)

    public class SampleContainerVM : DependencyObject
    {
        public static readonly DependencyProperty SampleListProperty =
DependencyProperty.Register("SampleList",
                        typeof(ObservableCollection<SampleVM>),
                        typeof(SampleContainerVM));

        public ObservableCollection<SampleVM> SampleList
        {
            get { return (ObservableCollection<SampleVM>)GetValue(SampleListProperty); }
            set { SetValue(SampleListProperty, value); }
        }

        public DelegateCommand AddCommand { get; set; }

        public SampleContainerVM()
        {
            SetValue(SampleListProperty, new ObservableCollection<SampleVM>());
            AddCommand = new DelegateCommand(
                AddSample,
                () => { return true; });
        }

        private void AddSample()
        {
            SampleList.Add(new SampleVM());
        }
    }

DataContext = new VM() в каждом xaml.cs

Теперь яможно добавить SampleControl к ListBox в SampleContainer, нажав кнопку.

Проблема заключается в том, что экземпляры (Title Property) в SampleList из SampleContainer не изменяются даже при изменении текстав представлении.

Должен ли я добавить какой-либо обработчик событий?

1 Ответ

0 голосов
/ 30 мая 2019

Я слишком много думал о DependencyProperty, и я должен думать просто. Мне не нужно DependencyProperty.

Я мог бы добиться того, что я хочу, следующим образом:

SampleVM.cs

public class SampleVM : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private string _title;
    public string Title
    {
        get { return _title; }
        set
        {
            _title = value;
            NotifyPropertyChanged();
        }
    }

    public SampleVM(string title="init")
    {
        Title = title;
    }
}

SampleContainerVM.cs

public class SampleContainerVM
{
    public ObservableCollection<SampleVM> SampleList { get; set; }

    public DelegateCommand AddCommand { get; set; }

    public SampleContainerVM()
    {
        SampleList = new ObservableCollection<SampleVM>();
        AddCommand = new DelegateCommand(
            AddSample,
            () => { return true; });
    }

    private void AddSample()
    {
        SampleList.Add(new SampleVM());
    }
}

SampleContainer.xaml (Удалить Sample.xaml и записать в <ListBox.ItemTemplate>)

<UserControl x:Class="Sample.SampleContainer"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Sample"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="2*" />
            <RowDefinition Height="1*" />
        </Grid.RowDefinitions>
        <ListBox
            ItemsSource="{Binding SampleList}"
            HorizontalContentAlignment="Stretch"
            VerticalContentAlignment="Stretch"
            Grid.Row="0"
            >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <TextBox
                        Margin="10"
                        Text="{Binding Title, UpdateSourceTrigger=PropertyChanged}"
                     >
                    </TextBox>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button
            Command="{Binding AddCommand}"
            Grid.Row="1"
            Margin="10">
            add Sample...
        </Button>
    </Grid>
</UserControl>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...