繁体   English   中英

WP8绑定未更新

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM