2013-10-19 22 views
2

我的問題是我使用我的視圖和我的數據之間的綁定,但它只有第一次,如果我再次更新我的數據後,我的視圖不更新。 (Windows手機8)Xaml C#綁定數據只有第一次

查看代碼:

<phone:LongListSelector x:Name="DataContextAction" DataContext="{Binding DataContextAction}" ItemsSource="{Binding}" HorizontalAlignment="Left" Height="665" Margin="10,10,0,0" VerticalAlignment="Top" Width="471"> 
     <phone:LongListSelector.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Margin="{StaticResource PhoneMargin}"> 
        <TextBlock Text="{Binding HardwareId}" Style="{StaticResource PhoneTextLargeStyle}"/> 
        <TextBlock Text="{Binding Type}" Style="{StaticResource PhoneTextNormalStyle}"/> 
        <TextBlock Text="{Binding Status}" Style="{StaticResource PhoneTextNormalStyle}"/> 
       </StackPanel> 
      </DataTemplate> 
     </phone:LongListSelector.ItemTemplate> 
    </phone:LongListSelector> 

xaml.cs頁:

public DevicePage() 
{ 
    InitializeComponent(); 

    // Display message waiting before make the http query. 
    txtMessage.Foreground = new SolidColorBrush(Colors.Orange); 
    txtMessage.Text = "Loading..."; 

    // Initialize the view data binding. 
    InitializeAsynch(); 

    // Start new thread in background. 
    var refreshViewBackground = new System.Threading.Thread(RefreshViewBackground); 
    refreshViewBackground.Start(); 
} 

private async void InitializeAsynch() 
{ 
    // TODO BAD CODE but I don't understand (and I don't have enough time) how make it better. http://blog.stephencleary.com/2013/01/async-oop-2-constructors.html 
    DataContext = await UserSession.RefreshLastLocationDevices(); 
    // If I do that now with empty session, the view will be empty. 
    //DataContextAction.ItemsSource = UserSession.Actions; 
    txtMessage.Text = ""; 
} 

當我開始一個新的動作我運行一個新的線程將更新當行動完成時的會話。 (在與先前的代碼相同的文件中)

private void StartListenNewAction(DataAction action, DataDevice device) 
{ 
    // Update the actions list; 
    try 
    { 
     DataContextAction.ItemsSource = UserSession.Actions; 
    } 
    catch (Exception e) 
    { 
     Debug.WriteLine("Unable to refresh, another thread has updated the action list. " + e.Message); 
    } 

    // Start new thread in background for this specific action. 
    ParameterizedThreadStart refreshActionBackground = new ParameterizedThreadStart(RefreshActionBackground); 
    Thread thread = new Thread(refreshActionBackground); 
    Thread.Start(new object[] { action, device }); 
} 

但是,這裏只有第一次工作。我的觀點只更新一次。 感謝您的幫助,我不明白,我使用另一個longListSelector,並且我沒有使用該會話的麻煩,但我直接使用{Binding},而不是名稱。

<phone:LongListSelector x:Name="listDevices" ItemsSource="{Binding}" ... 

所以,我不明白爲什麼它不起作用。

編輯: 至於問:

// Refresh only one action in background. 
public async void RefreshActionBackground(object args) 
{ 
    bool pending = true; 

    DataAction action = (DataAction)((object[])args)[0]; 
    DataDevice device = (DataDevice)((object[])args)[1]; 

    while (pending) 
    { 
     // Sleep some time. 
     System.Threading.Thread.Sleep(device.AskingFrequencyActive * 1000); 

     // Get the action from the web service. 
     List<Param> parameters = new List<Param>(); 
     parameters.Add(new Param("email", UserSession.Email)); 
     parameters.Add(new Param("password", UserSession.Password)); 
     parameters.Add(new Param("hardwareId", device.HardwareId));// Mandatory. 
     parameters.Add(new Param("id", action.Id)); 
     parameters.Add(new Param("limit", "1")); 

     // Send the request. 
     IDictionary<string, object> response = await WebService.Send("action", "find", parameters); 

     if ((bool)response["status"]) 
     { 
      // Get objects from the response. 
      Dictionary<string, object> data = (Dictionary<string, object>)response["data"]; 
      // We got an array, convert to array. 
      JsonArray actionsArray = (JsonArray)data["action"]; 

      // Update the session. 
      actionsArray.ForEach(delegate(dynamic actionJson) 
      { 
       // Update the action from the session. 
       UserSession.Actions.Where(s => (string)s.Id == (string)actionJson["id"]).First().Status = (string)actionJson["status"]; 

       // Get the action from the session. 
       DataAction actionSession = UserSession.Actions.Where(s => s.Id == action.Id).First(); 

       // Compare to the session which could be updated since the last time. 
       if (actionSession.Status == "Executed") 
       { 
        pending = false; 
        // Update UI thread. 
        Deployment.Current.Dispatcher.BeginInvoke(() => 
        { 
         // Update the actions list; 
         try 
         { 
          DataContextAction.ItemsSource = UserSession.Actions; 
         }catch(Exception e){ 
          Debug.WriteLine("Unable to refresh, another thread has updated the action list. " + e.Message); 
         } 

         // Update UI interface. 
         txtMessage.Foreground = new SolidColorBrush(Colors.Green); 
         this.txtMessage.Text = "Action executed: " + action.Type; 
        }); 
       } 
      }); 

     } 
     else 
     { 
      Debug.WriteLine((string)response["message"]); 
     } 
    } 
} 
+1

我會爲您提供閱讀 - 關於INotifyPropertyChanged http://www.codeproject.com/Articles/41817/Implementing-INotifyPropertyChanged –

+0

「RefreshActionBackground」和「RefreshViewBackground」定義在哪裏?你能證明嗎? –

+0

已更新主帖子。添加了RefreshActionBackground函數。 – Vadorequest

回答

0

正如我所說的那個項目已經結束了,但我想通了它是如何工作的,這是一種很糟糕的方式,實際上也是非常瘋狂的。

這很簡單,如果我的列表視圖constains多個設備,它的工作。如果只有一個,它不起作用。絕對不知道發生了什麼,我不再工作了,所以這是一個騙局,也許會發生在別人身上。

該項目託管在GIT中,在這裏:https://bitbucket.org/Vadorequest/trip-analyzer-server-node.js/overview

謝謝您的幫助。

0

我想你不應該使用一個新的線程。在系統用完之前,你基本上沒有理由宣稱新線程。請使用Tasks來代替。你確定你第二次在用戶界面應該更新時仍然在正確的線程上嗎?

+1

在RefreshActionBackground()函數中,我執行使用Deployment.Current.Dispatcher.BeginInvoke更新UI線程的代碼,所以我認爲它很好。在StartListenNewAction()函數中,我在UI線程中。無論如何,我會嘗試。我不知道任務,我用它來等待我的等待電話,但沒有更多。我真的沒有時間更新應用程序,我不知道什麼WP8視圖有24小時... – Vadorequest