2012-12-29 4 views
0

웹 사이트에서 데이터를 가져 와서 표시하는 WP8 앱을 만들려고합니다. 파노라마 템플릿을 선택하고 Visual Studio에서 기본 코드를 생성했습니다.WP8 바인딩 업데이트 안 함

내가하려는 것은 텍스트가 바인딩 된 변수를 변경하면 텍스트 블록이 자동으로 업데이트된다는 것입니다. 그러나 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)); 
     } 
    } 
} 

UPDATE 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; 
    } 
} 
[...] 

답변

0
<TextBlock.DataContext> 
    <ViewModels:MainViewModel/> 
</TextBlock.DataContext> 

이 새로운 MainViewModel 객체를 만들고이 객체 있지만 App 개체에 저장된 하나를 업데이트하지 않습니다 .

이 문제를 해결하려면 다음 App.ViewModel 객체

(TextBlock에의 데이터 컨텍스트를 설정할 필요가 없습니다)에 대한보기의 데이터 컨텍스트를 설정 추가 :

public void changeDate() 
{ 
    Date = "fu"; 
    App.ViewModel.Date = "bar"; 
} 
:이 코드를 사용하지 마십시오

이제 ViewModel은 앱에 대해 알고 있습니다. 그냥 사용 : 내가 무슨 일이 일어나고 생각하는 것은 당신의 이 같은 작업자 스레드에서 날짜 게터를 호출 될 수 있습니다 일부 작업자 스레드에서 호출 NotifyPropertyChanged이다

public void changeDate() 
{ 
    Date = "fu"; 
} 
+0

도움 낸다 "의 DataContext = App.ViewModel을;" MainPage 생성자에서 텍스트 블록이 비어 있습니다. – user1796724

+0

어디에서 App.ViewModel을 초기화합니까? 그 코드도 게시 할 수 있습니까? –

+0

추가 코드 조각 2 개를 추가했습니다. – user1796724

1

. UI 요소가 (메인 UI 스레드가 아닌) 작업자 스레드에서 데이터 게터를 호출하면 "잘못된 크로스 스레드 액세스"으로 끝납니다. 그렇다면 처리기 메인 스레드에서 호출해야합니다. 예를 들어

private void NotifyPropertyChanged(String propertyName) 
{ 
    PropertyChangedEventHandler handler = PropertyChanged; 
    if (null != handler) 
    { 
     Dispatcher dsp = Deployment.Current.Dispatcher; 
     dsp.BeginInvoke(() => { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     }); 
    } 
} 

내가 된 본체의 데이터 컨텍스트를 삭제하고 설정하는 경우가

관련 문제