UserControl ItemsControl绑定

时间:2012-02-14 09:21:41

标签: wpf binding user-controls itemscontrol

我正在开发一个包含TextBoxes的ItemsControl的UserControl。我有一个标题类,用于控制TextBlock的位置/文本

在Window XAML中

<local:UserControl1>
    <local:UserControl1.Captions>
        <local:Caption Foreground="Black" Size="10"  Text="{Binding Path=SomeText}" X="100" Y ="100"></local:Caption>
    </local:UserControl1.Captions>
</local:UserControl1>

ItemsControl是一个画布,其中dataTemplate是一个TextBox

<ItemsControl ItemsSource="{Binding Path=Captions}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas Background="Beige" Width="{Binding Path=Width}" Height="{Binding Path=Height}"  />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=Text}" Foreground="{Binding Path=Foreground}" FontSize="{Binding Path=Size}" ></TextBlock>

        </DataTemplate>
    </ItemsControl.ItemTemplate>
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Canvas.Top" Value="{Binding Path=Y,PresentationTraceSources.TraceLevel=High}" />
            <Setter Property="Canvas.Left" Value="{Binding Path=X,PresentationTraceSources.TraceLevel=High}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

在UserControl中是一个ObservableCollection“Caption”,它派生自Framework元素

public class Caption :FrameworkElement
{
    /// <summary>
    /// The actual text to display
    /// </summary>
    public string Text
    {
        get { return (string)GetValue(TextProperty); }
        set { SetValue(TextProperty, value); }
    }

    /// <summary>
    /// The font size
    /// </summary>
    public int Size
    {
        get { return (int)GetValue(SizeProperty); }
        set { SetValue(SizeProperty, value); }
    }

    /// <summary>
    /// The text foreground color
    /// </summary>
    public Brush Foreground
    {
        get { return (Brush)GetValue(ForegroundProperty); }
        set { SetValue(ForegroundProperty, value); }
    }

    /// <summary>
    /// The Top location of the text
    /// </summary>
    public double Y
    {
        get { return (double)GetValue(YProperty); }
        set { SetValue(YProperty, value); }
    }

    /// <summary>
    /// The left location of the text
    /// </summary>
    public double X
    {
        get { return (double)GetValue(XProperty); }
        set { SetValue(XProperty, value); }
    }

    public override string ToString()
    {
        return string.Format("Caption:{0}//{1}.{2}", this.X, this.Y, this.Text);
    }

    private static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string),
                                                                                          typeof(Caption),
                                                                                          new PropertyMetadata(
                                                                                              OnPropertyChanged));

    private static readonly DependencyProperty SizeProperty = DependencyProperty.Register("Size", typeof(int),
                                                                                          typeof(Caption),
                                                                                          new PropertyMetadata(
                                                                                              OnPropertyChanged));

    private static readonly DependencyProperty ForegroundProperty = DependencyProperty.Register("Foreground",
                                                                                                typeof(Brush),
                                                                                                typeof(Caption),
                                                                                                new PropertyMetadata
                                                                                                    (OnPropertyChanged));

    private static readonly DependencyProperty YProperty = DependencyProperty.Register("Y", typeof(double),
                                                                                       typeof(Caption),
                                                                                       new PropertyMetadata(
                                                                                           OnPropertyChanged));

    private static readonly DependencyProperty XProperty = DependencyProperty.Register("X", typeof(double),
                                                                                       typeof(Caption),
                                                                                       new PropertyMetadata(
                                                                                           OnPropertyChanged));

    private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var caption = (Caption)d;
    }
}

每次将标题添加到集合时,它都会添加到逻辑树

void Captions_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
    if(e.Action == NotifyCollectionChangedAction.Add)
    {
        foreach(Caption c in e.NewItems)
        {
            AddLogicalChild(c);
            c.DataContext = this.DataContext;

        }
    }
}

问题是Canvas.TopCanvas.Left的绑定无法正常工作

调试产生以下

  

System.Windows.Data警告:54:创建BindingExpression   (hash = 14626603)用于绑定(hash = 8360729)

     

System.Windows.Data警告:56:路径:'X'

     

System.Windows.Data警告:58:BindingExpression(hash = 14626603):   默认模式已解决为OneWay

     

System.Windows.Data警告:59:BindingExpression(hash = 14626603):   默认更新触发器已解析为PropertyChanged

     

System.Windows.Data警告:60:BindingExpression(hash = 14626603):   附加到WpfApplicationQuery.Caption.Left(hash = 33822626)

     

System.Windows.Data警告:65:BindingExpression(hash = 14626603):   解决来源

     

System.Windows.Data警告:68:BindingExpression(hash = 14626603):   找到数据上下文元素:Caption(hash = 33822626)(OK)

     

System.Windows.Data警告:76:BindingExpression(hash = 14626603):   使用根项目激活

     

System.Windows.Data警告:104:BindingExpression(hash = 14626603):   级别0的项目为空 - 无访问者

     

System.Windows.Data警告:78:BindingExpression(hash = 14626603):   TransferValue - 获得原始值{DependencyProperty.UnsetValue}

     

System.Windows.Data警告:86:BindingExpression(hash = 14626603):   TransferValue - 使用后备/默认值'NaN'

     

System.Windows.Data警告:87:BindingExpression(hash = 14626603):   TransferValue - 使用最终值'NaN'

     

System.Windows.Data错误:26:ItemTemplate和ItemTemplateSelector   对于已经属于ItemsControl容器类型的项目,将被忽略;   类型= '标题'

所以它似乎绑定不正确,我不知道最后一个错误意味着什么

此外,之前,我有从DependencyObject派生的Caption,并且一切正常(.i.e显示的东西),但Databinding除外。因此切换到framworkElement,如stackoverflow上的某处所述(以及我现在找不到的博客帖子)

修改2012-02-14 更改了第一个XAML示例代码

修改2012-02-14 Caption派生自FrameworkElement,因此它可以参与此处所述的数据绑定 http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/aff23943-5483-40b2-816b-4ce687bc6bf8/ 和这里 http://kentb.blogspot.com/2008_10_01_archive.html

如果Caption实现了INotifyPropertyChanged

<local:UserControl1>
    <local:UserControl1.Captions>
        <local:Caption Foreground="Black" Size="10"  Text="Hello" X="100" Y ="100"></local:Caption>
        <local:Caption Foreground="Black" Size="10"  Text="{Binding Path=Title}" X="100" Y ="100"></local:Caption>
    </local:UserControl1.Captions>
</local:UserControl1>

第一行有效。第二个没有,这个错误被追踪。

  

无法为目标元素

找到管理FrameworkElement或FrameworkContentElement

但是,如果Caption派生自FrameworkElement,它现在提供它自己的ItemTemplate 因此产生了与ItemTemplate / Selector相关的绑定错误。

0 个答案:

没有答案