简体   繁体   中英

Can Indexers of a property work in xaml binding in windows phone 8?

something i do wrong? anyone gives some suggestions

according to msdn

Indexers of a property can be specified within square brackets following the property name where the indexer is applied. For instance, the clause Path=ShoppingCart[0] sets the binding to the index that corresponds to how your property's internal indexing handles the literal string "0". Multiple indexers are also supported.

i put Indexers of a property in my xaml

<Image Source="{Binding ImagePathList[0]}" Height="50" Width="50" Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" Margin="0,7,7,0" Grid.RowSpan="2">

i do not give the viewmodel code because i am pretty sure ListImagePathList have data.

EDIT* more detail: ImagePathList[0] is a web image url

EDIT FOR Brendan

model is Article

public class Article : INotifyPropertyChanged
    {
        private long _Id;
        public long ID
        {
            get { return _Id; }
            set
            {
                if (_Id != value)
                {
                    _Id = value;
                    NotifyPropertyChanged();
                }
            }
        }


        private string _subject;
        public string Subject
        {
            get
            {
                return _subject;
            }
            set
            {
                if (_subject != value)
                {
                    _subject = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private string _words;
        public string Words
        {
            get
            {
                return _words;
            }
            set
            {
                if (_words != value)
                {
                    _words = value;
                    NotifyPropertyChanged();
                }
            }
        }

        private DateTime _publishDate;
        public DateTime PublishDate
        {
            get
            { return _publishDate; }
            set
            {
                if (_publishDate != value)
                {
                    _publishDate = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public List<string> ImagePathList = new List<string>();

        private string _firstImage;
        public string FirstImage
        {
            get
            {
                return _firstImage;
            }
            set
            {
                if (_firstImage != value)
                {
                    _firstImage = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

ArticleViewModel is in below; All data returned from network is correct!

public class ArticleListViewModel : INotifyPropertyChanged
    {    
        public ArticleListViewModel()
        {
            this.ArticleCollection = new ObservableCollection<Article>();                
        }

        public ObservableCollection<Article> ArticleCollection
        {
            get;
            private set;
        }

        public void LoadPage(int pageNumber)
        {
            if (pageNumber == 1)
            {
                this.ArticleCollection.Clear();
            }

            IsLoading = true;
            ReadArticleList(pageNumber);

        }

        private async void ReadArticleList(int pageNumber)
        {
            try
            {

                List<Article> articleList = new List<Article>();
                articleList = await CollectionHttpClient.GetArticlesByPageAsync(pageNumber);

                this.ArticleCollection.Add(item);

                }

            }
            catch(Exception ex)
            {
                if (ex.HResult == -2146233088 && ex.Message.Equals("Response status code does not indicate success: 404 ()."))
                {
                    MessageBox.Show("The network is not set right. Internet cannot be accessed.");
                }
                else
                {
                    MessageBox.Show("sorry, no data.");
                }

            }

        }

        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(String propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (null != handler)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }

The XAML code you show is fine.

There may be a problem with the DataContext . Maybe the page DataContext has not been set? Or maybe the the DataContext has changed eg inside an ItemTemplate

Otherise the problem is probably to do with the bound property. Try the following

private ObservableCollection<string> _imagePathList = new ObservableCollection<string>();
public ObservableCollection<string> ImagePathList {
    get { return this._imagePathList; }
    set {
        if (this._imagePathList != value)
        {
            this._imagePathList = value;
            // I'm going to assume you have the NotifyPropertyChanged
            // method defined on the view-model
            this.NotifyPropertyChanged();
        }
    }
}

ObservableCollection is in System.Collections.ObjectModel and is like List but if elements are added/removed then the PropertyChanged event is fired. Also note that any bound property must have a get associated with it for it to work at all.

Another possibility is that ImagePathList was not assigned to or is empty - in which case, make sure you assign to it!

In case you have not yet implemented the NotifyPropertyChanged method, here it is ...

public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

You will also need to add INotifyPropertyChanged interface to the containing class eg

public class MyViewModelClass : INoftifyPropertyChanged 
{
    ...
}

I think the problem concerns the place where your images come from. As it is said at MSDN :

You can set the Source by specifying an absolute URL (eg http://contoso.com/myPicture.jpg ) or specify a URL relative to the XAP file of your application.

You can set this property in XAML, but in this case you are setting the property as a URI. The XAML behavior relies on underlying type conversion that processes the string as a URI, and calls the BitmapImage(Uri) constructor. This in turn potentially requests a stream from that URI and returns the image source object.

Just for test - place some images in your project and then set ImagePathList to them. See if that works (it should as I think). Or see if you can get BitmapImage(ImagePathList);

It's hard for me to say now (as I don't know how your ImagePathList looks like) what could be a reason of the failure. But if I were you, I would test this.


I would advise to use a property (or you can use converter which will also do the job):

// a property in your class
public Uri FirstImage
{
   get
   {
        return new Uri(ImagePathList.FirstOrDefault(), UriKind.Absolute);
   }
}

On the other hand if you are downloading images to IsolatedStorage then you will have to use another property, that will load BitmapImage from IS:

public BitmapImage FirstImage // getter - BitmapImage
{
    get
    {
       if (String.IsNullOrEmpty(ImagePath[0])) return null;
       BitmapImage temp = new BitmapImage();

       using (IsolatedStorageFile ISF = IsolatedStorageFile.GetUserStoreForApplication())
       using (IsolatedStorageFileStream file = ISF.OpenFile(ImagePath[0], FileMode.Open, FileAccess.Read))
            temp.SetSource(file);
       return temp;
    }
}

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM