我在更新绑定时遇到问题。 但我认为解释我的问题最简单的方法是我的代码:
XAML
<StackPanel>
<StackPanel.Resources>
<Converter:Converter_Position x:Key="Position"/>
</StackPanel.Resources>
<TextBox Text="{Binding Path=Position.X, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Text="{Binding Path=Position, Converter={StaticResource PositionToStartPosition}, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
如果我更改第一个TextBox的Text,则第二个TextBox不会更新。
我的转换器:
class Converter_Position : IValueConverter
{
public object Convert(object value, Type t, object parameter, CultureInfo culture)
{
RaPoint Position = value as RaPoint;
return Position.ToString();
}
public object ConvertBack(object value, Type t, object parameter, CultureInfo culture)
{
throw new Exception();
}
}
债券类:
public class RaPoint : INodifyPropertyChanged
{
public RaPoint()
{
X = 0;
Y = 0;
}
public RaPoint(double X, double Y)
{
this.X = X;
this.Y = Y;
}
private const string XPropertyName = "X";
private double _X;
public double X
{
get
{
return _X;
}
set
{
_X = value;
RaisePropertyChanged(XPropertyName);
}
}
private const string YPropertyName = "Y";
private double _Y;
public double Y
{
get
{
return _Y;
}
set
{
_Y = value;
RaisePropertyChanged(YPropertyName);
}
}
public override string ToString()
{
return String.Format("X:{0} Y:{1}" , X.ToString(), Y.ToString());
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
的DataContext:
private const string PositionPropertyName = "Position";
private RaPoint _Position = new RaPoint();
public RaPoint Position
{
get
{
return _Position;
}
set
{
_Position = value;
RaisePropertyChanged(PositionPropertyName);
}
}
答案 0 :(得分:1)
如果您使用DataContext
实例(RaPoint
属性)设置窗口的Position
,那么您应该尝试以这种方式绑定:
<TextBox Text="{Binding Path=X, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Text="{Binding Converter={StaticResource PositionToStartPosition}, UpdateSourceTrigger=PropertyChanged}"/>
基本上,数据绑定在不同对象的两个属性之间建立连接。在第一行中,您绑定了在DataContext中设置的对象的属性。 Path
用于指定该对象的属性或可能指向属性的属性(假设X将具有属性Z,那么您可以执行类似Path=X.Z
的操作)。
关于第二个TextBox
,如果您未指定绑定Source
,Path
,RelativeSource
或ElementName
绑定使用control的DataContext。 DataContext
通过可视树从上层元素(例如Window)传递到下层元素(例如TextBox
)。
但这些建议无法解决您的问题。当您在第一个TextBox中更改X
的值时,Position
属性永远不会更改,因此不会调用RaisePropertyChanged
,并且不会更新第二个TextBox X的新值。如果您希望TextBox的值均为X
和Y
,请使用MultiBinding。在Window / UserControl中执行以下操作:
<TextBox Text="{Binding Path=X, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox>
<TextBox.Text>
<MultiBinding Converter="{StaticResource Position}">
<Binding Path="X" />
<Binding Path="Y" />
</MultiBinding>
</TextBox.Text>
</TextBox>
以这种方式更换转换器:
public class Converter_Position : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
return String.Format("X:{0} Y:{1}", values[0],values[1]);
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
答案 1 :(得分:0)
问题是转换器只在加载时才使用一次。 Position
DataContext
永远不会改变,因此在Position属性的setter中有一个RaisePropertyChnage
没有意义。删除它。
public RaPoint Position
{
get
{
return _Position;
}
set
{
_Position = value;
RaisePropertyChanged(PositionPropertyName);
}
}
到
public RaPoint Position
{
get; set;
}
接下来的事情是,您希望TextBox
每当X
更新Position
时,理想情况下,您不希望仅仅DataContext
绑定{{1}只会改变一次),你想绑定到Position.X
,因为属性改变了事件的地方是。通过这样做,转换器将每次X
更改时进行评估。你也想要只有Position
类,在转换器中传递。您需要更新转换器,以便将Position
传递给它。最简单的方法是使用MultiValuConverter传递给Parameter对象以及Paramter.X(它将用于监视更改)。
<TextBox>
<TextBox.Text>
<MultiBinding Converter="{StaticResource PositionToStartPosition}">
<Binding Path="Position.X" UpdateSourceTrigger="PropertyChanged"/>
<Binding Path="Position" />
</MultiBinding>
</TextBlock.Text>
</TextBox>
最后,更新您的转换器:
class Converter_Position : IMultiValueConverter
{
public object Convert(object[] values, Type t, object parameter, CultureInfo culture)
{
RaPoint Position = values[1] as RaPoint;
return Position.ToString();
}
public object ConvertBack(object[] values, Type t, object parameter, CultureInfo culture)
{
throw new Exception();
}
}