用户控件上的数据绑定问题 [英] Issue with DataBinding on a UserControl
问题描述
我遇到了一个非常基本的问题.
我已经创建了一个用户控件,例如这样的示例:
< UserControl x:Class ="
xmlns =" http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x =" >
< 网格 >
< TextBox =" txtMessage" 文本 {绑定消息,ElementName = root}" 宽度 高度 =" > < /TextBox >
< /Grid >
< /UserControl >
我创建了一个名为Message
的DependencyProperty
,我想与DataBinding一起使用.该代码如下所示:
公共 部分 class txtItem:UserControl
{
公共 静态 只读 DependencyProperty MessageProperty = DependencyProperty.注册(" , typeof ( 字符串), typeof (txtItem),新 UIPropertyMetadata(" ,textChangedCallback));
私有 静态 void textChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
txtItem输入=(txtItem)d;
input.txtMessage.Text = e.NewValue as String ;
}
公共 字符串消息
{
获取 {返回(字符串)GetValue( MessageProperty); }
set {SetValue(MessageProperty, value ); }
}
}
现在,一旦构建了控件,我就希望该控件能够与数据绑定一起使用,就像普通TextBox的工作方式一样.在我的窗口中,我将其用作:
< ListBox x:Name =" ItemsSource =" {绑定}" < ListBox.ItemTemplate >
< DataTemplate >
< StackPanel =" < TextBlock =" {Binding Name}" / < local:txtItem 水平对齐 =" 垂直对齐 中心" =" =" {绑定值}" >
< /StackPanel >
< /DataTemplate >
< /ListBox.ItemTemplate >
< /ListBox >
从后面的代码中:
私人List< Element> items = null;
私有 无效 Window_Loaded(对象发件人,RoutedEventArgs e)
{
此 .items = 新列表< Element>();
items.Add(新元素{名称= " ,值= " });
此 .lstBox.DataContext =项目;
}
Element类也可以从INotifyPropertyChanged实现:
public class 元素:INotifyPropertyChanged
{
私有 字符串 _Name;
公共 字符串名称
{
获取
{
返回 此.
}
设置
{
此._Name = 值;
此 .OnPropertyChanged(" ) ;
}
}
私有 字符串 _Value;
公共 字符串值
{
获取
{
返回 此 ._ Value;
}
设置
{
此._Value = 值;
此 .OnPropertyChanged(" ) ;
}
}
#region INotifyPropertyChanged成员
公共 虚拟 无效 OnPropertyChanged (字符串信息)
{
如果(此.PropertyChanged!= 空 )
此 .PropertyChanged(此,新 PropertyChangedEventArgs (信息));
}
公共 事件 PropertyChangedEventHandler PropertyChanged;
#endregion
}
现在,当我更改UserControl
内的Textbox
内的数据时,它不会更新实际对象.我什至从INotifyPropertyChanged
实现了UserControl
,并在TextBox
上的值更改时调用了该事件,但是but,它对我没有用.谁能在这方面帮助我.
如果您想查看代码,可以从这里下载:
TextCalc.zip(80 KB)
Hey Abhishek,
你错过了什么.通常,您的代码应该可以工作,但是有一个小错误.这是代码:
< ListBox x:Name =" ItemsSource {Binding}" < ListBox.ItemTemplate > < DataTemplate > < StackPanel =" < TextBlock =" {Binding Path = Name}" / > < local:txtItem 水平对齐 =" VerticalAlignment 中心" 宽度 =" 消息 =" > < /StackPanel > < /DataTemplate > < /ListBox.ItemTemplate > < /ListBox >
您的第一个错误是在这里:
< local:txtItem 水平对齐 =" =" 中心" =" 50" =" {绑定值,模式= TwoWay,UpdateSourceTrigger = PropertyChanged}" >
您没有为双向模式绑定它. :(
第二个错误是您的UserControl.同样,绑定不正确.这是代码:
<UserControl x:Name="userControl" x:Class="TextCalc.txtItem" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <TextBox Name="txtMessage" Text="{Binding Message, ElementName=userControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="30" Height="20"></TextBox> </Grid> </UserControl>
让我知道是否可以解决您的问题.如果它能解决您的查询,请不要忘记标记为答案".
谢谢&问候,
Kunal
尝试创建ObservableCollection
类型的对象.
然后,您用实际数据值填充此对象并将其绑定到您的listbox
.
public ObservableCollection<<Element>> MyCollection { get { return this._myCollection; } set { this._Value = value; this.OnPropertyChanged("MyCollection"); } }
注意:我必须使用两个<<>>对于上面的Element类,好像我没有使用它.
<listbox x:name="lstBox" itemssource="{Binding <b>MyCollection</b>}" xmlns:x="#unknown"> <listbox.itemtemplate> <datatemplate> <stackpanel orientation="Horizontal"> <textblock text="{Binding Name}" /> <local:txtitem horizontalalignment="Center" verticalalignment="Center" width="50" message="{Binding Value}" xmlns:local="#unknown" /> </stackpanel> </datatemplate> </listbox.itemtemplate> </listbox>
列表框和文本框的绑定不同,因为列表框绑定到itemssource集合.
举个简单的例子,在此处.
>
I am in a very basic problem.
I have created a user control, say sample like this :
<UserControl x:Class="TextCalc.txtItem"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<TextBox Name="txtMessage" Text="{Binding Message, ElementName=root}" Width="30" Height="20"></TextBox>
</Grid>
</UserControl>
I have created a DependencyProperty
named Message
which I want to work with DataBinding. The Code looks like :
public partial class txtItem : UserControl
{
public static readonly DependencyProperty MessageProperty = DependencyProperty.Register("Message",typeof(String),typeof(txtItem), new UIPropertyMetadata("0", textChangedCallback));
private static void textChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
txtItem input = (txtItem)d;
input.txtMessage.Text = e.NewValue as String;
}
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
}
Now once I built the control, I want this control to work with Databinding just like how normal TextBox works. In my Window, I used this as :
<ListBox x:Name="lstBox" ItemsSource="{Binding}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}" />
<local:txtItem HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Message="{Binding Value}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
From the codebehind :
private List<Element> items = null;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
this.items = new List<Element>();
items.Add(new Element { Name = "Abhishek", Value = "300" });
this.lstBox.DataContext = items;
}
The Element class is also implemented from INotifyPropertyChanged :
public class Element : INotifyPropertyChanged
{
private string _Name;
public string Name
{
get
{
return this._Name;
}
set
{
this._Name = value;
this.OnPropertyChanged("Name");
}
}
private string _Value;
public string Value
{
get
{
return this._Value;
}
set
{
this._Value = value;
this.OnPropertyChanged("Value");
}
}
#region INotifyPropertyChanged Members
public virtual void OnPropertyChanged(string info)
{
if(this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(info));
}
public event PropertyChangedEventHandler PropertyChanged;
#endregion
}
Now when I change the data within the Textbox
that comes within the UserControl
, it doesnt update the actual object. I have even implemented the UserControl
from INotifyPropertyChanged
, and invoked the event when the value is changed on the TextBox
, but alas, it didnt worked for me. Can anyone help me in this regard.
If you want to see the code you can download from here:
TextCalc.zip (80 KB)
Hey Abhishek,
You missed something. Generally your code should work but there was a small mistake. Here is the code:
<ListBox x:Name="lstBox" ItemsSource="{Binding}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <TextBlock Text="{Binding Path=Name}" /> <local:txtItem HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Message="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>
Your first mistake was here:
<local:txtItem HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Message="{Binding Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
You didn''t bind it for twoway mode. :(
Second mistake is in your UserControl. Samething, binding was not proper. Here is the code:
<UserControl x:Name="userControl" x:Class="TextCalc.txtItem" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <Grid> <TextBox Name="txtMessage" Text="{Binding Message, ElementName=userControl, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="30" Height="20"></TextBox> </Grid> </UserControl>
Let me know if it resolves your issue. Don''t forget to "Mark As Answer" if it resolves your query.
Thanks & Regards,
Kunal
Try by creating an object of typeObservableCollection
.
You then fill this object with actual data values and bind it to yourlistbox
.
public ObservableCollection<<Element>> MyCollection { get { return this._myCollection; } set { this._Value = value; this.OnPropertyChanged("MyCollection"); } }
Note: I had to use two <<>> for the Element class above as if I used one it was not appearing.
<listbox x:name="lstBox" itemssource="{Binding <b>MyCollection</b>}" xmlns:x="#unknown"> <listbox.itemtemplate> <datatemplate> <stackpanel orientation="Horizontal"> <textblock text="{Binding Name}" /> <local:txtitem horizontalalignment="Center" verticalalignment="Center" width="50" message="{Binding Value}" xmlns:local="#unknown" /> </stackpanel> </datatemplate> </listbox.itemtemplate> </listbox>
Listbox and Textbox binding are different as ListBox binds to an itemssource collection.
For a simple example, have a look here.
这篇关于用户控件上的数据绑定问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!