用户控件的DependencyProperty在ListView的结合 [英] UserControl DependencyProperty binding in ListView

查看:106
本文介绍了用户控件的DependencyProperty在ListView的结合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试在ListView使用自定义用户控件,它失败,只有空块显示(以下TextBlock的工作虽然)。而在ListView外customControl工作pretty好。有什么问题?


MainWindow.xaml

 <网格和GT;
    <&StackPanel的GT;
        <控制:CustomControl X:NAME =customControlCustomText =测试/>
        < ListView的X:名称=ListView控件>
            < ListView.ItemTemplate>
                <&DataTemplate的GT;
                    <&StackPanel的GT;
                        <控制:CustomControl CustomObject ={结合}/>
                        < TextBlock的文本={结合文字}/>
                    < / StackPanel的>
                < / DataTemplate中>
            < /ListView.ItemTemplate>
        < /&的ListView GT;
    < / StackPanel的>
< /网格和GT;

MainWindow.cs

 公共部分类主窗口:窗口
{
    公共主窗口()
    {
        的InitializeComponent();
        InitializeMyComponent();
    }    公共System.Collections.ObjectModel.ObservableCollection< CustomClass> CustomCollection的{搞定;组; }    私人无效InitializeMyComponent()
    {
        this.CustomCollection =新System.Collections.ObjectModel.ObservableCollection< CustomClass>();
        this.CustomCollection.Add(新CustomClass(){总数= 1,文本=A});
        this.CustomCollection.Add(新CustomClass(){总数= 2,文本=B});
        this.CustomCollection.Add(新CustomClass(){总数= 3,文本=C});
        this.listView.ItemsSource = this.CustomCollection;
        this.customControl.Custom =新CustomClass(){数= 0,文本=customControl};
    }
}

CustomControl.xaml

 <网格和GT;
    <&StackPanel的GT;
        <&的TextBlock GT;
            <运行X:NAME =numberRun文本={结合CustomObject.Number}/>
            <运行X:NAME =textRun文本={结合CustomObject.Text}/>
            <运行文本={结合CustomText}/>
        < / TextBlock的>
    < / StackPanel的>
< /网格和GT;

CustomControl.cs

 公共部分类CustomControl:用户控件
{
    公共静态只读的DependencyProperty CustomObjectProperty;
    公共静态只读的DependencyProperty CustomTextProperty;    静态CustomControl()
    {
        CustomObjectProperty = DependencyProperty.Register(CustomObject的typeof(CustomClass)的typeof(CustomControl),新PropertyMetadata(默认值(CustomClass),OnCustomObjectPropertyChanged));
        CustomTextProperty = DependencyProperty.Register(CustomText的typeof(串)的typeof(CustomControl),新PropertyMetadata(的String.Empty,OnCustomTextPropertyChanged));
    }
    公共CustomControl()
    {
        的InitializeComponent();
        this.DataContext =这一点;
    }    公共CustomClass CustomObject
    {
        得到
        {
            回报(CustomClass)(this.GetValue(CustomObjectProperty));
        }
        组
        {
            this.SetValue(CustomObjectProperty,值);
        }
    }
    公共字符串CustomText
    {
        得到
        {
            回报(字符串)(this.GetValue(CustomTextProperty));
        }
        组
        {
            this.SetValue(CustomTextProperty,值);
        }
    }    私有静态无效OnCustomObjectPropertyChanged(DependencyObject的D,DependencyPropertyChangedEventArgs E){}
    私有静态无效OnCustomTextPropertyChanged(DependencyObject的D,DependencyPropertyChangedEventArgs E){}
}

CustomClass.cs

 公共类CustomClass:INotifyPropertyChanged的
{
    私人诠释数目;
    私人字符串文本;    公共CustomClass()
    {
        this.number = INT新();
        this.text =的String.Empty;
    }    公众诠释号码
    {
        得到
        {
            返回this.number;
        }
        组
        {
            this.number =价值;
            this.OnPropertyChanged();
        }
    }
    公共字符串文本
    {
        得到
        {
            返回this.text;
        }
        组
        {
            this.text =价值;
            this.OnPropertyChanged();
        }
    }    公共事件PropertyChangedEventHandler的PropertyChanged;    保护无效OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName]字符串名称= NULL)
    {
        PropertyChangedEventHandler处理器= this.PropertyChanged;
        如果(处理!= NULL)
        {
            处理器(这一点,新PropertyChangedEventArgs(名));
        }
    }
}


解决方案

设置用户控件的的DataContext

的用户控件实例

  this.DataContext =这一点;

有效prevents绑定外部,继承的DataContext,如预期在

 <控制:CustomControl CustomObject ={结合}/>

作为一般规则,的从不的设置用户控件的DataContext的明确。在该用户的XAML与的RelativeSource取下用户控件的构造上面一行,并写入绑定:

 <运行X:NAME =numberRun文本={结合CustomObject.Number,
    的RelativeSource = {的RelativeSource AncestorType =用户控件}}/>

When I try to use a custom UserControl in a ListView, it fails and only empty blocks are displayed (the following TextBlock works though). While the customControl outside the ListView works pretty well. What's the problem?


MainWindow.xaml

<Grid>
    <StackPanel>
        <controls:CustomControl x:Name="customControl" CustomText="Test"/>
        <ListView x:Name="listView">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <StackPanel>
                        <controls:CustomControl CustomObject="{Binding}"/>
                        <TextBlock Text="{Binding Text}"/>
                    </StackPanel>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackPanel>
</Grid>

MainWindow.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        InitializeMyComponent();
    }

    public System.Collections.ObjectModel.ObservableCollection<CustomClass> CustomCollection { get; set; }

    private void InitializeMyComponent()
    {
        this.CustomCollection = new System.Collections.ObjectModel.ObservableCollection<CustomClass>();
        this.CustomCollection.Add(new CustomClass() { Number = 1, Text = "a" });
        this.CustomCollection.Add(new CustomClass() { Number = 2, Text = "b" });
        this.CustomCollection.Add(new CustomClass() { Number = 3, Text = "c" });
        this.listView.ItemsSource = this.CustomCollection;
        this.customControl.Custom = new CustomClass() { Number = 0, Text = "customControl" };
    }
}

CustomControl.xaml

<Grid>
    <StackPanel>
        <TextBlock>
            <Run x:Name="numberRun" Text="{Binding CustomObject.Number}"/>
            <Run x:Name="textRun" Text="{Binding CustomObject.Text}"/>
            <Run Text="{Binding CustomText}"/>
        </TextBlock>
    </StackPanel>
</Grid>

CustomControl.cs

public partial class CustomControl : UserControl
{
    public static readonly DependencyProperty CustomObjectProperty;
    public static readonly DependencyProperty CustomTextProperty;

    static CustomControl()
    {
        CustomObjectProperty = DependencyProperty.Register("CustomObject", typeof(CustomClass), typeof(CustomControl), new PropertyMetadata(default(CustomClass), OnCustomObjectPropertyChanged));
        CustomTextProperty = DependencyProperty.Register("CustomText", typeof(string), typeof(CustomControl), new PropertyMetadata(string.Empty, OnCustomTextPropertyChanged));
    }
    public CustomControl()
    {
        InitializeComponent();
        this.DataContext = this;
    }

    public CustomClass CustomObject
    {
        get
        {
            return (CustomClass)(this.GetValue(CustomObjectProperty));
        }
        set
        {
            this.SetValue(CustomObjectProperty, value);
        }
    }
    public string CustomText
    {
        get
        {
            return (string)(this.GetValue(CustomTextProperty));
        }
        set
        {
            this.SetValue(CustomTextProperty, value);
        }
    }

    private static void OnCustomObjectPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { }
    private static void OnCustomTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { }
}

CustomClass.cs

public class CustomClass : INotifyPropertyChanged
{
    private int number;
    private string text;

    public CustomClass()
    {
        this.number = new int();
        this.text = string.Empty;
    }

    public int Number
    {
        get
        {
            return this.number;
        }
        set
        {
            this.number = value;
            this.OnPropertyChanged();
        }
    }
    public string Text
    {
        get
        {
            return this.text;
        }
        set
        {
            this.text = value;
            this.OnPropertyChanged();
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string name = null)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

解决方案

Setting a UserControl's DataContext to the UserControl instance like

this.DataContext = this;

effectively prevents bindings to an "external", inherited DataContext, as expected in

<controls:CustomControl CustomObject="{Binding}"/>

As a general rule, never set a UserControl's DataContext explicitly. Remove the above line from the UserControl's constructor, and write the bindings in the UserControl's XAML with RelativeSource:

<Run x:Name="numberRun" Text="{Binding CustomObject.Number,
    RelativeSource={RelativeSource AncestorType=UserControl}}"/>

这篇关于用户控件的DependencyProperty在ListView的结合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆