【问题标题】:WPF binding ObservableCollection<string> to ItemsControl not working [closed]WPF 将 ObservableCollection<string> 绑定到 ItemsControl 不起作用 [关闭]
【发布时间】:2012-09-07 12:00:16
【问题描述】:

我有一些字符串属性需要解析内容,并显示在单独的控件中。假设有电子邮件和网址用空格分隔。显示电子邮件工作正常,但网址却不行。代码如下:

XAML 文件:

<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# 文件:

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

我已经调试了 Grid_LayoutUpdated,它工作正常。它会在需要时触发,并且 UrlsCollection 包含所需的数据。正如我所说,EmailTextBox 显示数据,但 ItemsControl 一直是空的。更有趣的是,从超链接绑定中删除“Path=/”会引发 XAML Parse 异常。我已经没有想法了... 我已经阅读了一些主题,但没有一个有用

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?

【问题讨论】:

    标签: c# wpf data-binding observablecollection itemscontrol


    【解决方案1】:

    Path=/ 绑定到当前项目集合而不是正在模板化的当前项目,通常说当前项目是一个被选中的(见IsSynchronizedWithCurrentItem)。您的DataContext 是一个字符串而不是一个集合,因此尝试通过/ 绑定到当前项目将失败(请参阅binding errors)。

    要绑定到 正在模板化的当前项目,您需要直接绑定到 DataContext,这可以通过 {Binding}{Binding .}/{Binding Path=.} 完成(如果属性需要Binding.Path 选择后者之一)。

    【讨论】:

      【解决方案2】:

      您的超链接控件需要一个用于 NavigateUri 属性的 Uri,但您只需绑定到一个字符串。

      实现您想要的一种方法是使用转换器进行 NavigateUri 绑定

      <Hyperlink NavigateUri="{Binding Path=., Converter={StaticResource YourStringToUriConverterGoesHere}}" Click="EmailAsWWW_Click">
        <Run Text="{Binding}" />
      </Hyperlink>
      

      另一种方法是更改​​集合

      public ObservableCollection<MyUrlWrapper> UrlsProperty
      {
          get;
          private set;
      }
      
      public class MyUrlWrapper
      {
          public string Url {get;set;}
          public Uri MyUri {get{return new Uri(this.Url);}}
      }
      
      <Hyperlink NavigateUri="{Binding Path=MyUri}" Click="EmailAsWWW_Click">
        <Run Text="{Binding Path=Url}" />
      </Hyperlink>
      

      【讨论】:

      • 检查并没有帮助:(我相信这不是问题。我之前使用过没有转换器的 Hyerplink,它工作正常。无论如何感谢您的回复。
      • 请尝试: 只是为了查看集合不为空且绑定正确。
      • 还有一件事-您的输出窗口中是否存在任何绑定错误?您还可以使用 Snoop 检查绑定错误。
      【解决方案3】:

      试试:

      <Hyperlink NavigateUri="{Binding}" Click="EmailAsWWW_Click">
          <Run Text="{Binding}" />
      </Hyperlink>
      

      【讨论】:

      • 更有趣的是,从超链接绑定中删除“Path=/”会引发 XAML Parse 异常。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-14
      • 2012-07-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多