簡體   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