【发布时间】:2016-09-10 02:27:08
【问题描述】:
我遇到了奇怪的问题,我无法理解。在主页中,我只有一个按钮可以导航到第二页并保存我的模型:
public class Model : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaiseProperty(string property) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property));
private int index = 0;
public int Index
{
get { Debug.WriteLine($"Getting value {index}"); return index; }
set { Debug.WriteLine($"Setting value {value}"); index = value; RaiseProperty(nameof(Index)); }
}
}
public sealed partial class MainPage : Page
{
public static Model MyModel = new Model();
public MainPage()
{
this.InitializeComponent();
SystemNavigationManager.GetForCurrentView().AppViewBackButtonVisibility = AppViewBackButtonVisibility.Visible;
SystemNavigationManager.GetForCurrentView().BackRequested += (s, e) => { if (Frame.CanGoBack) { e.Handled = true; Frame.GoBack(); } };
}
private void Button_Click(object sender, RoutedEventArgs e) => Frame.Navigate(typeof(BlankPage));
}
在第二页只有 ComboBox 在 SelectedIndex 中有双向绑定:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<ComboBox SelectedIndex="{x:Bind MyModel.Index, Mode=TwoWay}">
<x:String>First</x:String>
<x:String>Second</x:String>
<x:String>Third</x:String>
</ComboBox>
</Grid>
public sealed partial class BlankPage : Page
{
public Model MyModel => MainPage.MyModel;
public BlankPage()
{
this.InitializeComponent();
this.Unloaded += (s, e) => Debug.WriteLine("--- page unloaded ---");
DataContext = this;
}
}
没什么特别的。问题是当我使用Binding 和x:Bind 时会得到两个不同的输出,但最糟糕的是,在每次新导航到同一页面后,属性的getter(和x:Bind 中的setter)被调用的次数越来越多:
旧页面仍然驻留在内存中,并且仍然订阅属性,这是可以理解的。如果我们从页面返回后运行GC.Collect(),我们将从头开始。
但如果我们使用旧的 Binding 和 one-way 并且选择更改事件:
<ComboBox SelectedIndex="{Binding MyModel.Index, Mode=OneWay}" SelectionChanged="ComboBox_SelectionChanged">
连同事件处理程序:
private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.RemovedItems.Count > 0 && e.AddedItems.FirstOrDefault() != null)
MyModel.Index = (sender as ComboBox).Items.IndexOf(e.AddedItems.FirstOrDefault());
}
那么它将“正常”工作 - 只有一个 getter 和 setter,无论我们之前导航到页面多少次。
所以我的主要问题是:
- one-way - two-way 绑定的差异从何而来?
- 考虑到 单向绑定 只触发一次 getter - 所描述的 双向 行为是否需要/有意?
- 在调用多个 getter/setter 的情况下,您如何处理这种 双向 绑定?
一个工作示例,您可以download from here。
【问题讨论】:
-
这是因为你的静态模型实例吗?只是我的猜测。
-
@KiranPaul 不,使用非静态它的行为完全相同。我几乎可以肯定它与内存有某种联系——如果我在返回主页后触发
GC.Collect(),那么我又回到了开始。不过我不知道为什么这两个绑定有这么大的不同,为什么单向 getter 总是被调用一次。
标签: c# windows data-binding win-universal-app windows-10