c# - Xaml C# 绑定(bind)数据仅在第一次有效

标签 c# xaml binding windows-phone-8

我的问题是我在我的 View 和我的数据之间使用了绑定(bind),但它只在第一次工作,如果我再次更新我的数据,我的 View 不会更新。 (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 = "";
}

当我开始一个新 Action 时,我会运行一个新线程,该线程将在该 Action 完成时更新 session 。 (与之前的代码在同一个文件中)

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"]);
        }
    }
}

最佳答案

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

关于c# - Xaml C# 绑定(bind)数据仅在第一次有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19468916/

相关文章:

wpf - 通过XAML将Window.Content设置为页面吗?

c# - 为什么我需要一个评估者而不是直接从我的绑定(bind)对象数据属性中获取我的值

c# - 创建客户端列表时,Address 应该是一个结构体(类客户端)吗?

c# - 动态地将 JavaScript 文件添加到正文而不是头部

c# - 如何将参数传递给 MySQL OdbcCommand 并且仅当谓词匹配时如何更新?

c# - 如何在 ListView 的组标题中保存 IsExpanded 状态

c# - WPF:FlowDirection.RightToLeft 如何更改字符串?

binding - 如何绑定(bind)属性 block monotouch

WPF 绑定(bind)到控件模板上的非依赖属性

java - 在 Saucelabs 中使用 Selenium 远程 Firefox Webdriver 安装扩展时出现问题