wpf 如何将ListView的ItemsSource设置为自定义UserControl内的DependencyProperty?[副本]

c0vxltue  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(89)

此问题已在此处有答案

Issue with DependencyProperty binding(3个答案)
15天前关闭。
我有一个自定义用户控件,如下所示:

<ListView Name="listView" SelectionChanged="ListView_SelectionChanged" ItemsSource="{Binding Containers}">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Info" Width="150">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <TextBlock Text="{Binding Info}"/>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
public partial class ContainerList : UserControl
{
    public IEnumerable<Container> Containers
    {
        get { return (IEnumerable <Container>)GetValue(ContainersProperty); }
        set { SetValue(ContainersProperty, value); }
    }

    public static readonly DependencyProperty ContainersProperty =
        DependencyProperty.Register("Containers", typeof(IEnumerable<Container>), typeof(ContainerList), new PropertyMetadata(null));

    public ContainerList()
    {
        InitializeComponent();
        this.DataContext = this;
        listView.ItemsSource = Containers;
    }

    private void ListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (listView.SelectedItem != null)
        {
            var selectedContainer = (Container)listView.SelectedItem;
            if (selectedContainer.Children.Any())
            {
                childContainerList.Visibility = Visibility.Visible;
                childContainerList.ItemsSource = selectedContainer.Children;
            }
        }
    }
}

我在MainWindow中创建它,像这样:

<Window x:Class="WpfApp1.MainWindow"
        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:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        d:DataContext="{d:DesignInstance local:MainWindow}"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <local:ContainerList Containers="{Binding Containers}"/>
    </Grid>
</Window>
public partial class MainWindow : Window, INotifyPropertyChanged
{
    public ObservableCollection<Container> Containers
    {
        get => _containers;
        set
        {
            _containers = value;
            OnPropertyChanged();
        }
    }
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }
}

这种控制最终将是递归的。现在的问题是,ListView根本没有填充。如何做到这一点?

zzlelutf

zzlelutf1#

不能将UserControl的DataContext显式设置为自身,因为这会破坏标准数据绑定行为。在UserControl构造函数中设置ListView的ItemsSource也没有意义,因为XAML中已经有一个Binding。

public ContainerList()
{
    InitializeComponent();
}

然而,绑定应该使用UserControl示例作为其源对象,例如:就像这样:

ItemsSource="{Binding Containers,
              RelativeSource={RelativeSource AncestorType=UserControl}}"

需要注意的是,new PropertyMetadata(null)会将dependency属性的PropertyChangedCallback设置为null,而不是默认值。
除非你真的想设置任何特定的值,否则不要传递属性元数据:

public static readonly DependencyProperty ContainersProperty =
    DependencyProperty.Register(
        nameof(Containers),
        typeof(IEnumerable<Container>),
        typeof(ContainerList));

相关问题