简体   繁体   English

无法在 ListView 的 UWP 中使用自定义控件绑定属性

[英]Unable to bind properties using custom controls in UWP in a ListView

I have a ListView in UWP which displays a list of custom controls CustomControl .我在 UWP 中有一个ListView ,它显示自定义控件CustomControl的列表。 Reading around I have seen that other users have face similar issues and their solution mostly revolved around setting the DataContext of their controls, but I cannot understand how I can do that in my example.阅读周围,我发现其他用户也遇到了类似的问题,他们的解决方案主要围绕设置控件的DataContext展开,但我无法理解如何在我的示例中做到这一点。 In order to dynamically update the view I used DependencyProperties in my model which is the following:为了动态更新视图,我在模型中使用了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"));
    }

Then in my main page I implemented the following logic to change the Name of my third element:然后在我的主页中,我实现了以下逻辑来更改我的第三个元素的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!";

        }
    }

The XAML for the main page is the following:主页的 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>

The custom control CustomControl is this:自定义控件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();
        }
    }

Its structure is very simple:它的结构非常简单:

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

The problem is that when I click the button nothing happens and I am struggling to understand why.问题是当我点击按钮时没有任何反应,我很难理解为什么。

DataObject shouldn't inherit from DependencyObject . DataObject不应继承自DependencyObject It should be defined as a CLR object that implements INotifyPropertyChanged :它应该定义为实现INotifyPropertyChanged的 CLR 对象:

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));
    }
}

Also, the setter of the CLR wrapper for the dependency property in CustomControls should only set the value of the dependency property.此外, CustomControls中依赖属性的 CLR 包装器的设置器应该设置依赖属性的值。 You could set the value of the TextBlock using a PropertyChangedCallback :您可以使用PropertyChangedCallback设置TextBlock的值:

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();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM