我的问题是我在视图和数据之间使用绑定,但它只在第一次工作,如果我再次更新我的数据,我的视图不会更新。 (Windows Phone 8)
查看代码:
<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"]);
}
}
}
答案 0 :(得分:0)
我认为你不应该使用新线程。在系统耗尽之前,你基本上没有任何理由要求新线程。请转而使用Tasks。你确定第二次用户界面应该更新时你是否还在正确的线程上?
答案 1 :(得分:0)
正如我所说的那个项目已经结束但是我发现它是如何运作的,实际上是一种糟糕的方式而且非常疯狂。
这很简单,如果我的列表视图不止一个设备,它就可以了。如果只有一个,它就不起作用了。绝对不知道发生了什么,我不再继续工作,所以这是一个伎俩,也许会发生在其他人身上。
项目托管在git上,在这里:https://bitbucket.org/Vadorequest/trip-analyzer-server-node.js/overview
感谢您的帮助。