Search code examples
c#xamldata-bindingwindows-8linq-to-twitter

LINQ to Twitter setting users account image c#


I am attempting to fetch the users profileImageURl and bind it to an image. I have got the following C# code:

namespace IIVVYTwitter
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            DataContext = new ViewModel(this);
        }
    }

    class ViewModel : INotifyPropertyChanged
    {

        public User AccountImageUrl { get; set; }

        readonly Page page;

        public ViewModel(Page page)
        {
            this.page = page;
            LoadAccount = new TwitterCommand<object>(LoadAccountHolder);
        }


        public TwitterCommand<object> LoadAccount { get; set; }

        void LoadAccountHolder(object obj)
        {
            PinAuthorizer auth =
            new PinAuthorizer
            {
                Credentials = new LocalDataCredentials()
            };

            if (auth == null || !auth.IsAuthorized)
            {
                page.Frame.Navigate(typeof(oAuth));
                return;
            }

            var twitterCtx = new TwitterContext(auth);

            var accounts =
                from acct in twitterCtx.Account
                where acct.Type == AccountType.VerifyCredentials
                select acct;

            Account account = accounts.SingleOrDefault();
            LinqToTwitter.User user = account.User;

            new User
                 {
                     AccountImageUrl = user.ProfileImageUrl
                 };


            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("AccountImageUrl"));
            }
        }

    }
}

Linked with this XAML:

<Page
    x:Class="IIVVYTwitter.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:IIVVYTwitter"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

<Grid>
    <Button Command="{Binding LoadAccount}">
         <Border>
              <Image x:Name="accountPicture" Source="{Binding AccountImageUrl}" />
         </Border>
    </Button>
</Grid>
</Page>

When I run the command through a button click, the code runs but the source of the Image is not updated.

I'm pretty sure the way I have bound the source data is flawed.

Thanks in advance.


Solution

  • I do not see you setting the DataContext for the page anywhere. Without a properly defined DataContext, the Bindings you are using cannot be resolved to any data object. A simple example would be in the OnNavigatedTo method or the page's constructor, you need to do something like:

    this.DataContext = new ViewModel()
    

    or something similar. There are different ways to wire up the data context depending on how you want handle viewmodel creation, lifetime, etc., but hopefully this gets you on the right path. In your code, you could also call page.DataContext = this; in your constructor.

    Update: You also need to fix the code when you fire the PropertyChanged event. You have

    if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("ImageUrl"));
                }
    

    should be

    if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs("AccountImageUrl"));
                }
    

    Notice the change to the string passed for the property name. You were firing an change event for a property that did not exist.

    Update #2: You are returning a type of User from AccountImageUrl. You should be returning the actual http url string, not a custom type. If User has a property that hanging off of it that points to the http Url, you could update the Xaml Binding to AccountImageUrl.PropertyThatContainsRealUrl

    Update #3: In your code, you have

    new User
                     {
                         AccountImageUrl = user.ProfileImageUrl
                     };
    

    This is setting the AccountImageUrl on the new User object. However, you are binding to the AccountImageUrl of the ViewModel. At some point, you have to set AccountImageURl to the image url string and raise PropertyChanged on AccountImageURL. So, either before or after creating a new User, you should say this.AccountImageUrl = user.ProfileImageUrl. Hopefully I am still following your code and the changes you have made in the comments correctly.