Невозможно связать свойства с помощью пользовательских элементов управления в UWP в ListView - PullRequest
1 голос
/ 24 января 2020

У меня есть ListView в UWP, который отображает список пользовательских элементов управления CustomControl. Читая вокруг, я видел, что другие пользователи сталкиваются с подобными проблемами, и их решение в основном вращалось вокруг установки DataContext их элементов управления, но я не могу понять, как я могу это сделать в моем примере. Чтобы динамически обновлять представление, я использовал DependencyProperties в моей модели, а именно:

    public class DataObject : DependencyObject
    {
        public string Name
        {
            get { return (string)GetValue(nameProperty); }
            set { SetValue(nameProperty, value); }
        }

        // Using a DependencyProperty as the backing store for name.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty nameProperty =
            DependencyProperty.Register("Name", typeof(string), typeof(DataObject), new PropertyMetadata("Name"));
    }

Затем на своей главной странице я реализовал следующую логику c, чтобы изменить Name моего третий элемент:

    public sealed partial class MainPage : Page
    {
        private readonly ObservableCollection<DataObject> dataList;

        public MainPage()
        {
            this.InitializeComponent();
            this.dataList = new ObservableCollection<DataObject>();

            for (int i = 0; i < 5; i++)
            {
                DataObject dataObject = new DataObject();
                dataObject.Name = "Item " + i.ToString();

                this.dataList.Add(dataObject);
            }
            DataListView.ItemsSource = dataList;

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            var obj = dataList.ElementAt(2);

            obj.Name = "Hello!";

        }
    }

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

<Page
    x:Class="ListViewTest.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:controls="using:ListViewTest.Controls"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <ListView Name="DataListView">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <controls:CustomControl DisplayName="{Binding Name}"></controls:CustomControl>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <Button Content="Button" HorizontalAlignment="Center" Height="92" Width="238"
                Click="Button_Click"/>
    </Grid>
</Page>

Пользовательский элемент управления CustomControl имеет следующий вид:

namespace ListViewTest.Controls
{
    public sealed partial class CustomControl : UserControl
    {


        public string DisplayName
        {
            get { return (string)GetValue(DisplayNameProperty); }
            set { 
                SetValue(DisplayNameProperty, value);
                DisplayText.Text = value;
            }
        }

        // Using a DependencyProperty as the backing store for DisplayName.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DisplayNameProperty =
            DependencyProperty.Register("DisplayName", typeof(string), typeof(CustomControl), new PropertyMetadata("DisplayText"));


        public CustomControl()
        {
            this.InitializeComponent();
        }
    }

Его структура очень проста:

    <Grid>
        <Button Name="ClickButton" Content="Button" Margin="171,165,0,0" VerticalAlignment="Top"/>
        <TextBlock Name="DisplayText" HorizontalAlignment="Center" TextWrapping="Wrap" VerticalAlignment="Center"/>
    </Grid>

Проблема в том, что когда я нажимаю кнопку, ничего не происходит, и я пытаюсь понять, почему.

1 Ответ

1 голос
/ 24 января 2020

DataObject не должно наследоваться от DependencyObject. Он должен быть определен как объект CLR, который реализует INotifyPropertyChanged:

public class DataObject : INotifyPropertyChanged
{
    private string _name;
    public string Name
    {
        get { return _name; }
        set { _name = value; OnPropertyChanged(); }
    }

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

Кроме того, установщик оболочки CLR для свойства зависимостей в CustomControls должен only установить значение свойства зависимости. Вы можете установить значение TextBlock, используя PropertyChangedCallback:

public sealed partial class CustomControl : UserControl
{
    public string DisplayName
    {
        get { return (string)GetValue(DisplayNameProperty); }
        set { SetValue(DisplayNameProperty, value); }
    }

    public static readonly DependencyProperty DisplayNameProperty =
        DependencyProperty.Register(nameof(DisplayName), typeof(string), typeof(CustomControl), 
            new PropertyMetadata("DisplayText", new PropertyChangedCallback(OnChanged)));

    private static void OnChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CustomControl customControl = (CustomControl)d;
        d.DisplayText = e.NewValue as string;
    }

    public CustomControl()
    {
        this.InitializeComponent();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...