所以,我有这个非常简单的代码,当我在使用注释的代码行时单击一个按钮时,GUI中的值是通过更新的绑定更新,一切正常。如果我使用另外两行(没有发生),即使我注意到改变,也没有任何反应。
public partial class MainWindow : Window, INotifyPropertyChanged
{
private Spot _position = new Spot(0, 0);
public Spot Position
{
get { return _position; }
set { _position = value; OnPropertyChanged("Position"); }
}
public MainWindow()
{
InitializeComponent();
win.DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string name)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//Position = new Spot(5,5);
Position.UpdateX(5);
OnPropertyChanged("Position");
}
}
public class Spot
{
public Spot(int x, int y)
{
X = x;
Y = y;
}
public void UpdateX(int x)
{
X += x;
}
public void UpdateY(int y)
{
Y += y;
}
public override string ToString()
{
return string.Format("{0}; {1}", X, Y);
}
public int X { get; set; } = 0;
public int Y { get; set; } = 0;
}
XAML
<StackPanel x:Name="win" Orientation="Vertical" Margin="100">
<Label Content="{Binding Position, UpdateSourceTrigger=PropertyChanged}" Width="100" Height="25"></Label>
<Button Width="100" Height="25" Click="Button_Click">Click</Button>
</StackPanel>
提前感谢任何建议。
答案 0 :(得分:0)
这是这笔交易。
首先,摆脱UpdateSourceTrigger=PropertyChanged
:该标志控制Mode=TwoWay
Binding
何时更新其源属性。 Label.Content
默认绑定OneWay
,因为它不是可编辑的控件。它无法更新其来源。所以不管怎么说,这是一个无操作。
第二
<Label Content="{Binding Position}" ... />
这样做会在ToString()
上致电Position
。但如果ToString()
的值未发生变化,则不会再次致电Position
。从相关意义上讲,它还没有Spot
的同一个实例,它是最后一次调用ToString()
。这可能是一个优化&#34;。
这将有效:
<Label>
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0}: {1}">
<Binding Path="Position.X" />
<Binding Path="Position.Y" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</Label>
这也可以:
<Label>
<TextBlock>
<TextBlock Text="{Binding Position.X, StringFormat='{}{0}: '}" />
<TextBlock Text="{Binding Position.Y}" />
</TextBlock>
</Label>
我将TextBlock
放在Label
中,因为您使用的是Label
,而Label
通常有默认的边距/填充/与布局相关的任何样式看起来正确。
此无效,因为Label.Content
为Object
,而非String
,因此StringFormat
将被忽略。相反,您会在VS 输出窗格中获得有关需要转换器的MultiBinding
的例外情况:
<Label
>
<Label.Content>
<MultiBinding StringFormat="{}{0}: {1}">
<Binding Path="Position.X" />
<Binding Path="Position.Y" />
</MultiBinding>
</Label.Content>
</Label>
执行此操作的常用方法是Spot
实施INotifyPropertyChanged
。如果Spot
的总体使用情况不适合这样做,那么您就会陷入或多或少的丑陋行为。我自己,我给了Position
所有者一个UpdatePosition(int deltaX, int deltaY)
方法,该方法会创建Spot
的新实例并将其分配给Position
。如果viewmodel的属性(或伪装成viewmodel的窗口)不实现INotifyPropertyChanged
,则将属性值视为不可变。