当底层集合的相应属性更改时,silverlight 文本框不会更新
作为一个例子,
我有两个文本框。两个文本框的文本都绑定到类名称{String fullname, String funguName};它们不是直接绑定的,而是通过转换器绑定的。
它们正在实现 INotifyChanged,绑定的 DataContext 是 ObservableCollection 以及所有其他标准内容。
该模板已绑定,因此我一行有 2 个文本框,列表框有 10 行 问题是:
当我更改文本框 1 中的全名时,我去更改绑定集合中的有趣名称。
这不会立即反映到 GUI 上。
我怎样才能实现这个目标?我不想更新整个列表框,也不想直接将其绑定到类中的另一个属性,而是通过转换器。当属性从“TOm”更改为“dick”时,不会调用转换器,即仅第一次调用转换器。接下来,每当某些属性发生更改并被
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("FunnyName"));
调用时,都不会调用转换器。
原始代码中添加了
集合类
public class VariableData : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
String _Source;
/// <summary>
/// Gets or sets the source.
/// </summary>
/// <value>
/// The source.
/// </value>
public String Source
{
get { return _Source; }
set
{
_Source = value; if (this.PropertyChanged != null)
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Source"));
}
}
}
绑定
<TextBox Name="textBoxFileLocation"
Text="{Binding Converter={StaticResource mapTypeToDataConverter}, ConverterParameter=41}"
Margin="5,5,5,5" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2">
</TextBox>
转换器
public class MapTypeToDataConverter : IValueConverter
{
#region IValueConverter Members
/// <summary>
/// Modifies the source data before passing it to the target for display in the UI.
/// </summary>
/// <param name="value">The source data being passed to the target.</param>
/// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param>
/// <param name="parameter">An optional parameter to be used in the converter logic.</param>
/// <param name="culture">The culture of the conversion.</param>
/// <returns>
/// The value to be passed to the target dependency property.
/// </returns>
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return "";
VariableData cus = null;
try
{
cus = (VariableData)value;
}
catch (Exception e3)
{
return null;
}
if (cus == null)
return "";
int temp = int.Parse(parameter.ToString());
int mapType = temp / 10;
int whatToreturn = temp % 10;
if (mapType != cus.MappingType)
{
if (whatToreturn == 3)
return false;
else
return "";
}
switch (whatToreturn)
{
case 1:
return cus.Source;
break;
case 2:
return cus.Query;
break;
case 3:
if (cus.Source != null && cus.Source.Length > 0)
return true;
else
return false;
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value;
}
#endregion IValueConverter Members
}
As an example
I have a 2 text boxes. Text of both text boxes are bound to class Name {String fullname, String funnyName}; They are not directly bound but by a converter
They are implementing INotifyChanged
and the bound DataContext
is ObservableCollection
and all other standard stuff.
This template is bound so that I have 2 text boxes in one row and the listbox has 10 rows
THe question is :
when I change fullname in text box 1, I go and change the funnyname in the bound collection.
This is not not reflected immediately onto the GUI.
How can I achieve this? I don't want to update entire list box, and I don't want to directly bind it to another property in my class, but through a converter. The converter is not called when property changes from say "TOm" to "dick" i.e converter is only called first time. Next whenever some property changes and
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("FunnyName"));
is called, the converter is not invoked.
have added the original code
the collection class
public class VariableData : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
String _Source;
/// <summary>
/// Gets or sets the source.
/// </summary>
/// <value>
/// The source.
/// </value>
public String Source
{
get { return _Source; }
set
{
_Source = value; if (this.PropertyChanged != null)
this.PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs("Source"));
}
}
}
the binding
<TextBox Name="textBoxFileLocation"
Text="{Binding Converter={StaticResource mapTypeToDataConverter}, ConverterParameter=41}"
Margin="5,5,5,5" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2">
</TextBox>
the converter
public class MapTypeToDataConverter : IValueConverter
{
#region IValueConverter Members
/// <summary>
/// Modifies the source data before passing it to the target for display in the UI.
/// </summary>
/// <param name="value">The source data being passed to the target.</param>
/// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param>
/// <param name="parameter">An optional parameter to be used in the converter logic.</param>
/// <param name="culture">The culture of the conversion.</param>
/// <returns>
/// The value to be passed to the target dependency property.
/// </returns>
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null)
return "";
VariableData cus = null;
try
{
cus = (VariableData)value;
}
catch (Exception e3)
{
return null;
}
if (cus == null)
return "";
int temp = int.Parse(parameter.ToString());
int mapType = temp / 10;
int whatToreturn = temp % 10;
if (mapType != cus.MappingType)
{
if (whatToreturn == 3)
return false;
else
return "";
}
switch (whatToreturn)
{
case 1:
return cus.Source;
break;
case 2:
return cus.Query;
break;
case 3:
if (cus.Source != null && cus.Source.Length > 0)
return true;
else
return false;
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)value;
}
#endregion IValueConverter Members
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您似乎将整个
VariableData
绑定为值,然后使用转换器提取所需的输出。由于VariableData
实例本身没有改变(您的ConvertBack
没有返回VariableData
类型的新对象),因此 UI 没有理由相信它需要更新其 UI。您应该做的是删除转换器并绑定到
VariableData
的属性,将所需的逻辑移动到VariableData
中,根据需要创建其他属性。如果更改一个属性也会影响另一个属性,您可以确保为这两个属性引发PropertyChanged
事件。You appear to be binding the whole
VariableData
as the value then using a converter to extract the output you need. Since theVariableData
instance itself isn't changing (yourConvertBack
is not returning a new object of typeVariableData
) there is no reason for the UI to believe that it needs to update its UI.What you should do is drop the converter and bind to properties of
VariableData
move the logic you need intoVariableData
create additional properties as necessary. If changing one property affects also another you can ensure thatPropertyChanged
events are raised for both.您是否在 XAML 中设置了
Mode=TwoWay
:(目前不在 IDE 中,因此可能存在拼写错误)
这意味着当
MyProperty 时 UI 会更新当 UI 更改时,
会更改,MyProperty
也会更新。Have you set
Mode=TwoWay
in the XAML:(not at an IDE at the moment so there might be typos)
This will mean that the UI updates when
MyProperty
changes as well asMyProperty
updating when the UI changes.