WPF binding ObservableCollection<string> to ItemsControl not working

I have some string property that content need to be parsed, and displayed in separate controls. Let's say there are e-mails and urls separated by whitespaces. Displaying emails works fine, but urls don't. Here's code:

XAML file:

<ScrollViewer Grid.Row="0" Grid.Column="5" >
        <StackPanel Orientation="Vertical">
            <TextBox Name="EmailTextBox"
                     Text="{Binding ElementName=candidatePersonalDataViewControl, Mode=OneWay, Path=Candidate.Email, Converter={StaticResource emailConverter}}"/>

            <ItemsControl ItemsSource="{Binding ElementName=candidatePersonalDataViewControl, Mode=OneWay, Path=UrlsProperty}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <TextBlock
                            Margin="0,0,0,0"
                            Padding="5,2,5,2"
                            HorizontalAlignment="Left"
                            VerticalAlignment="Top">
                            <Hyperlink NavigateUri="{Binding Path=/}" 
                                       Click="EmailAsWWW_Click">
                                <Run Text="{Binding Path=/}" />
                            </Hyperlink>
                        </TextBlock>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <VirtualizingStackPanel Orientation="Vertical" />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
            </ItemsControl>
        </StackPanel>
    </ScrollViewer>

C# file:

    private static readonly DependencyProperty CandidateProperty = DependencyProperty.Register("Candidate", typeof(Candidate), typeof(CandidatePersonalDataViewControl));
    public Candidate Candidate
    {
        get { return (Candidate)GetValue(CandidateProperty); }
        set { SetValue(CandidateProperty, value); }
    }

    public CandidatePersonalDataViewControl()
    {
        InitializeComponent();
        this.DataContext = this;
        UrlsProperty = new ObservableCollection<string>();
    }

    public ObservableCollection<string> UrlsProperty
    {
        get;
        private set;
    }

    private void Grid_LayoutUpdated(object sender, EventArgs e)
    {
        if (Candidate == null)
            return;
        if (Candidate.Email == null)
            return;


        EmailPropertyToEmailsConverter emailConverter = new EmailPropertyToEmailsConverter();
        bool emails = (emailConverter.Convert(Candidate.Email, typeof(string), null, null) as string) != null;
        this.EmailTextBox.Visibility = emails ? Visibility.Visible : Visibility.Collapsed;

        EmailPropertyToUrlListConverter urlConverter = new EmailPropertyToUrlListConverter();
        IList<string> urls = urlConverter.Convert(Candidate.Email, typeof(string), null, null) as IList<string>;
        UrlsProperty.Clear();
        if (urls != null)
            foreach (string url in urls)
                UrlsProperty.Add(url);
    }

I have debugged Grid_LayoutUpdated and it works fine. It's fired whenever it's needed and UrlsCollection contains desired data. As I said, EmailTextBox displays the data, but ItemsControl is empty all the time. What is more interesing, removing "Path=/" from Hyperlink bindings raises an XAML Parse exception. I've run out of ideas... I have read some topics, but none was helpful

wpf ItemsControl binding problem

WPF Binding Path=/ not working?

WPF - bind a listbox to a list<string> - what am I doing wrong?

How do you bind ObservableCollections to ItemsSource?

Answers


Path=/ binds to the current item of a collection not the current item that is being templated, usually said current item is the one that is selected (see IsSynchronizedWithCurrentItem). Your DataContext is a string and not a collection, hence trying to bind to a current item via / will fail (see binding errors).

To bind to the current item that is being templated you need to bind directly to the DataContext which can be done via {Binding} or {Binding .}/{Binding Path=.} (if the property requires a Binding.Path choose one of the latter).


Need Your Help

C++ IO file streams: writing from one file to another using operator<< and rdbuf()

c++ stl fstream ifstream

I have a question about copying data from one file to another in C++ (fstream) using operator&lt;&lt;. Here is a code snippet that works for me:

Simple Java network IO is not working for large data

java io network-programming

I'm experiencing a strange problem that does not appear on MACOS but only linux...

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.