[英]WP8 Binding not updating
我正在尝试创建一个WP8应用程序,该应用程序从网站获取数据并显示它们。 我选择了全景图模板,Visual Studio创建了一些默认代码。
我想做的是,如果我更改文本绑定到的变量,文本块将自动更新。 但是调用changeDate()不会更改UI。 该文本框仍显示“ dd.mm.yyyy”。
MainPage.xaml:
<phone:LongListSelector.ListHeaderTemplate>
<DataTemplate>
<Grid Margin="12,0,0,38">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock
Text="{Binding Date}"
Style="{StaticResource PanoramaItemHeaderTextStyle}"
Grid.Row="0">
<TextBlock.DataContext>
<ViewModels:MainViewModel/>
</TextBlock.DataContext>
</TextBlock>
</Grid>
</DataTemplate>
</phone:LongListSelector.ListHeaderTemplate>
。
MainViewModel.cs:
public class MainViewModel : INotifyPropertyChanged
{
[...]
private string _date = "dd.mm.yyyy";
public string Date
{
get
{
return _date;
}
set
{
if (value != _date)
{
_date = value;
NotifyPropertyChanged("Date");
}
}
}
//public void changeDate()
//{
// Date = "fu";
// App.ViewModel.Date = "bar";
//}
**UPDATE 2**
public bool IsDataLoaded
{
get;
private set;
}
public void LoadData()
{
System.Net.WebClient wc = new System.Net.WebClient();
wc.DownloadStringCompleted += wc_DownloadStringCompleted;
wc.DownloadStringAsync(new Uri("somelink"));
}
private void wc_DownloadStringCompleted(object sender, System.Net.DownloadStringCompletedEventArgs e)
{
string s = FilterData(e.Result);
}
private string FilterData(string s)
{
string[] split = System.Text.RegularExpressions.Regex.Split(s, "<tbody>");
s = split[1];
split = System.Text.RegularExpressions.Regex.Split(s, "</tbody>");
s = split[0];
split = System.Text.RegularExpressions.Regex.Split(s, "\r\n");
foreach(string str in split)
{
if (str.Contains("class=\"xl24\""))
{
App.ViewModel.Date = "somedate";
}
}
return s;
}
**END UPDATE 2**
[...]
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
更新1
MainPage.xaml.cs:
public MainPage()
{
InitializeComponent();
DataContext = App.ViewModel;
}
**UPDATE 2**
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (!App.ViewModel.IsDataLoaded)
{
App.ViewModel.LoadData();
}
}
**END UPDATE 2**
[...]
。
App.xaml.cs:
private static MainViewModel viewModel = null;
public static MainViewModel ViewModel
{
get
{
if (viewModel == null)
viewModel = new MainViewModel();
return viewModel;
}
}
[...]
我认为正在发生的是,您的NotifyPropertyChanged是从某些工作线程中调用的,这可能导致从同一工作线程中调用Date getter。 如果UI元素从工作线程(而非主UI线程)调用数据获取程序,则操作以“ 无效的跨线程访问 ”结束。 如果是这样,则应从Main线程进行处理程序调用。 例如:
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
Dispatcher dsp = Deployment.Current.Dispatcher;
dsp.BeginInvoke(() => {
handler(this, new PropertyChangedEventArgs(propertyName));
});
}
}
希望能帮助到你
<TextBlock.DataContext>
<ViewModels:MainViewModel/>
</TextBlock.DataContext>
这将创建一个新的MainViewModel对象,而不是更新此对象,而是更新存储在App对象中的对象。
解决此问题的方法:将View的数据上下文设置为App.ViewModel对象(无需设置TextBlock的数据上下文)
附加:请不要使用此代码:
public void changeDate()
{
Date = "fu";
App.ViewModel.Date = "bar";
}
现在,您的ViewModel知道了该应用程序。 只需使用:
public void changeDate()
{
Date = "fu";
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.