locked
[UWP][C#] Issue Adding String Properties Bound To View RRS feed

  • Question

  • I'm having issues adding together string properties - one of which is bound to my view.

    walmartUrl = "http://api.walmartlabs.com/v1/items?apiKey=xxxxxxxx&upc=";
                    
                    url = (walmartUrl + upc);
    
                    var client = new HttpClient();
                    var walmartResponse = await client.GetAsync(new Uri(url));

    private string WalmartUrl { get; set; } public string walmartUrl { get { return WalmartUrl; } set { WalmartUrl = value; } } private string Url { get; set; } public string url { get { return Url; } set { Url = value; } }

    private string UPC { get; set; }
            public string upc
            {
                get
                {
                    return UPC;
                }
                set
                {
                    UPC = value;
                    OnPropertyChanged("upc");
                }
            }
    For some reason, url is only assigning to the walmartUrl string and not the UPC string + the Walmart string as shown below.

    upc is bound to a search field in the view of the program - and it's assigning properly with the binding as the pictures above show.

    What I don't understand is how url is assigning to walmartUrl instead of walmartUrl + upc. The last picture above shows when I hover over the + operator. 

    Debug.WriteLine(url) says that the value of url is

    http://api.walmartlabs.com/v1/items?apiKey=XXXXXXXXX77pnkv7nnss52p&upc=

    The full function that uses these methods - although it definitely isn't fully developed, is below. I haven't added exception handling or handled the case that the html client doesn't find a good web page.

    public async void searchWalmartNF(bool found)
            {
                //try
                //{
                    walmartUrl = "http://api.walmartlabs.com/v1/items?apiKey=XXXXXXXXX77pnkv7nnss52p&upc=";
                    
                    url = (walmartUrl + upc);
                    Debug.WriteLine(url);
    
                    var client = new HttpClient();
                    var walmartResponse = await client.GetAsync(new Uri(url));
                    var text = await walmartResponse.Content.ReadAsStringAsync();
                    JObject jsonText = JObject.Parse(text);
    
                    string jsonString = (string)jsonText["items"][0]["salePrice"];
    
                    if(jsonString != "") //If there was text find in salePrice
                    {
                        found = true;
                        Double.TryParse(jsonString, out onlinePrice);
    
                        bool walmartIndex = false;
                        int i = 0;
                        for (; (i < 49) && (walmartIndex = false) ; ++i) //Find walmart percentage
                        {
                            string nfcollection = nfbManager.nfCollection[i].retailer;
                            Debug.WriteLine(nfcollection);
                            if (nfbManager.nfCollection[i].retailer == "Walmart")
                            {
                                walmartIndex = true;
                            }
                        }
    
                        if (walmartIndex)
                        {
                            onlinePrice *= (nfbManager.nfCollection[i].percentage / 100);
                        }
                        else
                        {
                            var messageDialog = new MessageDialog("No Walmart information in the calculator was found.");
                            await messageDialog.ShowAsync();
                        }
                    }
                //}
                //catch (HttpRequestException httpException)
                //{
                //    Debug.WriteLine("HTTP exception caught.");
                //    Debug.WriteLine(httpException);
                //}
                //catch(Exception exception)
                //{
                //    Debug.WriteLine("Exception caught.");
                //    Debug.WriteLine(exception);
                //}
            } 

    I didn't think the code below the assignment of url was relevant (and it's sloppy at the moment b/c I couldn't get the strings to add as expected).

    And here is the binding for upc (which the binding seems to be working fine as shown in the pictures above)

    <StackPanel Orientation="Horizontal">
                        <TextBox Width="250" HorizontalAlignment="Left" KeyDown="{x:Bind nfViewModel.UPCSearch}" Name="UPCTextBox" Text="{Binding upc, Mode=TwoWay}"/>
                    </StackPanel>

    The KeyDown event in the view model:

     public async void UPCSearch(object sender, KeyRoutedEventArgs e)
            {
                if (e.Key == Windows.System.VirtualKey.Enter)
                {
                    try
                    {
                        searchWalmartNF(found);
                    }
                    catch (HttpRequestException httpException)
                    {
                        Debug.WriteLine("HTTP exception caught.");
                        Debug.WriteLine(httpException);
                    }
                    catch (Exception exception)
                    {
                        Debug.WriteLine("Exception caught.");
                        Debug.WriteLine(exception);
                    }
    
                    if(found)
                    {
                        operationClicked = false;
                        calculated = true;
                        hasDecimal = false;
                        displayText = onlinePrice.ToString();
                    }
                    else
                    {
                        var messageDialog = new MessageDialog("No price was found online.");
                        await messageDialog.ShowAsync();
                    }
                    //var xml = XElement.Parse(text);
                    //var titles = xml.Element("channel").Elements("item").Select(i => i.Element("title").Value);
    
                    //walmartPrice = Convert.ToString(titles);
                }
            }

    The xaml.cs for the page:

     public NewCalculator()
            {
                this.InitializeComponent();
                nfViewModel = new NFCalculatorViewModel();
                DataContext = nfViewModel;
            }
    
            public NFCalculatorViewModel nfViewModel { get; set; }

    The actual exception that the program produces is as follows when the keydown event is an enter key in the textbox (it's designed works with a scanner - the last keystroke after a scanner enters in the barcode number is enter)

    I believe the exception has to do with a bad web page. Since url doesn't contain the upc code, and just the Walmart url and the api key, it produces a bad web page.

    The big thing I found interesting was the above code logic works when the code is in the xaml.cs instead of the view model (below):

    private async void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
            {
                if (e.Key == Windows.System.VirtualKey.Enter)
                {
                    string walmartSearch = "http://api.walmartlabs.com/v1/items?apiKey=XXXXXXXXXXXpnkv7nnss52p&upc=";
                    upc = UPCTextBox.Text;
                    string searchString = walmartSearch + upc;
                    var text = "";
                    try
                    {
                        var client = new HttpClient();
                        var response = await client.GetAsync(searchString);
                        text = await response.Content.ReadAsStringAsync();
                        JObject jsonString = JObject.Parse(text);
    
                        salePrice = (string)jsonString["items"][0]["salePrice"];
    
                        IntermediateTextBlock.Text = salePrice;
                    }
                    catch (HttpRequestException httpException)
                    {
                        Debug.WriteLine("HTTP exception caught.");
                        Debug.WriteLine(httpException);
                    }
                    catch(Exception exception)
                    {
                        Debug.WriteLine("Exception caught.");
                        Debug.WriteLine(exception);
                    }
                    
                    //var xml = XElement.Parse(text);
                    //var titles = xml.Element("channel").Elements("item").Select(i => i.Element("title").Value);
    
                    //walmartPrice = Convert.ToString(titles);
                }

    That code snippet is in the xaml.cs - and it works to my complete perplexity; however, I want it to be in the view model with the rest of the code that I have for the page. I think it will create a lot of work to put it in the xaml.cs.

    If any more information is needed please let me know.

    Edit: If anyone tries to use the code with the api key provided above - it won't work. I used "xxxx" to censor the api key.










    Friday, August 16, 2019 3:55 PM

Answers

  • Hi,

    Try changing the binding method of the TextBox:

    <TextBox Width="250" HorizontalAlignment="Left" KeyDown="{x:Bind nfViewModel.UPCSearch}" Name="UPCTextBox" Text="{Binding upc, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>

    The problem is not that the strings are added, but that the changes to the control are not applied to the properties.

    For Mode=TwoWay, the default trigger is when the control loses focus. When you press the Enter key, the TextBox still holds the focus. At this time, the Text of the TextBox are not applied to the upc attribute, which causes the upc to be actually null.

    Best regards.



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, August 20, 2019 2:31 AM