无法获得从 Xaml 到 ObservableCollection 工作的双向绑定
Cant get twoWay Binding from Xaml to ObservableCollection Working
我正在尝试将 gridView 绑定到 Windows Store 应用程序中的 ObservableCollection。我的问题是我得到了数据,但设置似乎不起作用
public class ValveData : INotifyPropertyChanged
{
private string valveName;
private decimal waterMl;
private decimal waterEc;
private decimal waterPh;
public string ValveName
{
get { return this.valveName; }
set
{
this.valveName = value;
this.OnPropertyChanged("ValveName");
}
}
public decimal WaterMl
{
get { return this.waterMl; }
set
{
this.waterMl = value;
this.OnPropertyChanged("WaterMl");
}
}
public decimal WaterEc
{
get { return this.waterEc; }
set
{
this.waterEc = value;
this.OnPropertyChanged("WaterEc");
}
}
public decimal WaterPh
{
get { return this.waterPh; }
set
{
this.waterPh = value;
this.OnPropertyChanged("WaterPh");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class ValveDataCollection : ObservableCollection<ValveData>
{
public ValveDataCollection() : base()
{
Add(new ValveData { ValveName = "Valve 1", WaterMl = 100, WaterEc = 3, WaterPh = 5 });
Add(new ValveData { ValveName = "Valve 2" });
Add(new ValveData { ValveName = "Valve 3" });
Add(new ValveData { ValveName = "Valve 4" });
}
}
这是我的 Xaml
<data:ValveDataCollection x:Key="ValvesData"/>
<GridView x:Name="gw1" Grid.Row="2" ItemsSource="{StaticResource ValvesData}">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding ValveName, Mode=TwoWay}"/>
<TextBox Text="{Binding WaterMl, Mode=TwoWay}"/>
<TextBox Text="{Binding WaterEc, Mode=TwoWay}"/>
<TextBox Text="{Binding WaterPh, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
我确定我遗漏了一些东西,但我已经查看这段代码好几天了,还是想不通
该字符串看起来有效,这意味着如果我有 2 个文本框链接到 ValveName 字符串,则设置字符串并获取数据,但它看起来不适用于小数,它们在启动时获取数据,但如果您在文本框它似乎不影响变量
正确的 XAML 应该是
<TextBox Text="{Binding ValveName, Mode=TwoWay}"/>
而不是
<TextBox Text="{Binding ValveName}, Mode=TwoWay"/>
编辑
旁注:
此代码不是线程安全的。在 this.PropertyChanged != null
和 this.PropertyChanged
之间,另一个线程可能取消订阅并且 PropertyChanged
变为 null
。
public void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
始终使用事件处理程序的本地副本!
public void OnPropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
这个现在是线程安全的
对于未来的读者:对于 C# 6.0 (Visual Studio 2015),您还可以使用以下版本,该版本更短 和 线程安全,使用新的 "Null Propagation Operator" 运算符。
public void OnPropertyChanged(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
我正在尝试将 gridView 绑定到 Windows Store 应用程序中的 ObservableCollection。我的问题是我得到了数据,但设置似乎不起作用
public class ValveData : INotifyPropertyChanged
{
private string valveName;
private decimal waterMl;
private decimal waterEc;
private decimal waterPh;
public string ValveName
{
get { return this.valveName; }
set
{
this.valveName = value;
this.OnPropertyChanged("ValveName");
}
}
public decimal WaterMl
{
get { return this.waterMl; }
set
{
this.waterMl = value;
this.OnPropertyChanged("WaterMl");
}
}
public decimal WaterEc
{
get { return this.waterEc; }
set
{
this.waterEc = value;
this.OnPropertyChanged("WaterEc");
}
}
public decimal WaterPh
{
get { return this.waterPh; }
set
{
this.waterPh = value;
this.OnPropertyChanged("WaterPh");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public class ValveDataCollection : ObservableCollection<ValveData>
{
public ValveDataCollection() : base()
{
Add(new ValveData { ValveName = "Valve 1", WaterMl = 100, WaterEc = 3, WaterPh = 5 });
Add(new ValveData { ValveName = "Valve 2" });
Add(new ValveData { ValveName = "Valve 3" });
Add(new ValveData { ValveName = "Valve 4" });
}
}
这是我的 Xaml
<data:ValveDataCollection x:Key="ValvesData"/>
<GridView x:Name="gw1" Grid.Row="2" ItemsSource="{StaticResource ValvesData}">
<GridView.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding ValveName, Mode=TwoWay}"/>
<TextBox Text="{Binding WaterMl, Mode=TwoWay}"/>
<TextBox Text="{Binding WaterEc, Mode=TwoWay}"/>
<TextBox Text="{Binding WaterPh, Mode=TwoWay}"/>
</StackPanel>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
我确定我遗漏了一些东西,但我已经查看这段代码好几天了,还是想不通 该字符串看起来有效,这意味着如果我有 2 个文本框链接到 ValveName 字符串,则设置字符串并获取数据,但它看起来不适用于小数,它们在启动时获取数据,但如果您在文本框它似乎不影响变量
正确的 XAML 应该是
<TextBox Text="{Binding ValveName, Mode=TwoWay}"/>
而不是
<TextBox Text="{Binding ValveName}, Mode=TwoWay"/>
编辑 旁注:
此代码不是线程安全的。在 this.PropertyChanged != null
和 this.PropertyChanged
之间,另一个线程可能取消订阅并且 PropertyChanged
变为 null
。
public void OnPropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
始终使用事件处理程序的本地副本!
public void OnPropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
这个现在是线程安全的
对于未来的读者:对于 C# 6.0 (Visual Studio 2015),您还可以使用以下版本,该版本更短 和 线程安全,使用新的 "Null Propagation Operator" 运算符。
public void OnPropertyChanged(string propertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}