2

我的问题是我在我的视图和我的数据之间使用绑定,但它只在第一次工作,如果我再次更新我的数据,我的视图不会更新。(Windows 手机 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,使用session没有问题,但是我直接用的是{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"]);
        }
    }
}
4

2 回答 2

0

我认为您不应该使用新线程。在系统用完它们之前,您基本上是无缘无故地要求新线程。考虑改用任务。您确定您在第二次应该更新用户界面时仍然在正确的线程上吗?

于 2013-10-19T18:04:56.243 回答
0

正如我所说的项目已经结束,但我想出了如何让它工作,实际上是一种糟糕的方式,绝对是疯狂的。

这很简单,如果我的列表视图包含多个设备,它就可以工作。如果只有一个,它就不起作用。完全不知道发生了什么,我也不再处理它了,所以这是一个技巧,也许会发生在其他人身上。

该项目托管在 git 上,此处:https ://bitbucket.org/Vadorequest/trip-analyzer-server-node.js/overview

感谢您的帮助。

于 2013-11-26T22:59:31.530 回答