Xaml 绑定到依赖项集合的项

Xaml 绑定到依赖项集合的项,xaml,binding,custom-controls,Xaml,Binding,Custom Controls,我正在尝试创建一个具有页眉、页脚和正文的自定义控件。其思想是,报告主体是一个自定义堆栈面板控件,允许用户指示页面方向和分组。我在自定义UC上创建了一个dependency属性,以接受自定义堆栈面板的IList。我试图做的是绑定到列表中的一个堆栈面板。但由于某些原因,绑定不起作用 报告页面: public class ReportPage : StackPanel { //Nothing right now but will eventually include controls for

我正在尝试创建一个具有页眉、页脚和正文的自定义控件。其思想是,报告主体是一个自定义堆栈面板控件,允许用户指示页面方向和分组。我在自定义UC上创建了一个dependency属性,以接受自定义堆栈面板的IList。我试图做的是绑定到列表中的一个堆栈面板。但由于某些原因,绑定不起作用

报告页面:

public class ReportPage : StackPanel
{
    //Nothing right now but will eventually include controls for page orientation and size (8.5x11, 11x17, etc.)
}
用户控制代码隐藏:

public partial class Report : UserControl, INotifyPropertyChanged
{
    public Report()
    {
        ReportPages = new List<ReportPage>();
    }

    public static readonly DependencyProperty =
        DependencyProperty.Register("ReportPages", typeof(IList), typeof(Report));

    public IList ReportPages
    {
        get => (IList)GetValue(ReportPagesProperty);
        set
        {
            SetValue(ReportPagesProperty, value);
            ActivePage = value[0];
            OnPropertyChanged(nameof(ActivePage));
        }
    }

    private ReportPage _activePage;
    public ReportPage ActivePage
    {
         get => _activePage;
         set
         {
             _activePage = value;
             OnPropertyChanged(nameof(ActivePage));
         }
    {
}
公共部分类报告:UserControl,INotifyPropertyChanged
{
公开报告(
{
ReportPages=新列表();
}
公共静态只读从属属性=
从属财产登记簿(“报告页”、类型(IList)、类型(报告));
公共IList报告页
{
get=>(IList)GetValue(ReportPagesProperty);
设置
{
设置值(ReportPagesProperty,value);
ActivePage=值[0];
OnPropertyChanged(nameof(ActivePage));
}
}
私有报告页(activePage),;
公共报告页活动页
{
get=>\u activePage;
设置
{
_activePage=值;
OnPropertyChanged(nameof(ActivePage));
}
{
}
UserControl xaml:

<Grid>
    <!--Some xaml for the header and footer.-->
    <ContentControl Content="{Binding ActivePage, RelativeSource={RelativeSource, FindAncestor, AncestorType=local:Report}}"/>
</Grid>

下面是我使用自定义控件的方式。在我看来,这至少可以创建三个“页面”,我可以在使用我没有共享的按钮控件之间切换

<reportEngine:Report>
    <reportEngine:Report.ReportPages>

        <reportEngine:ReportPage>
            <TextBlock>This is Page 1</TextBlock>
        </reportEngine:ReportPage>

        <reportEngine:ReportPage>
            <TextBlock>This is Page 2</TextBlock>
        </reportEngine:ReportPage>

        <reportEngine:ReportPage>
            <TextBlock>This is Page 3</TextBlock>
        </reportEngine:ReportPage>

    </reportEngine:Report.ReportPages>
</reportEngine:Report>

这是第一页
这是第2页
这是第3页

知道绑定不起作用的原因吗?

所以我至少找到了一个快速解决方法。我利用answer中的集合更改事件处理程序模式,并将其修改为静态依赖属性。然后,为了从绑定到依赖属性的集合中获取值,我在constru中创建了报表对象的静态实例ctor并使用它将各种值从集合传递回对象。类似如下:

public partial class Report : UserControl, INotifyPropertyChanged
{
    private static Report _thisReport;

    public Report()
    {
        InitializeComponent();
        ReportPages = new ObservableCollection<ReportPage>();
        _thisReport = this;
    }

    public static readonly DependencyProperty ReportPagesProperty =
        DependencyProperty.Register("ReportPages", typeof(IList), typeof(Report), new FrameworkPropertyMetadata(ReportPagesChanged));

    public IList ReportPages
    {
        get => (IList)GetValue(ReportPagesProperty);
        set
        {
            SetValue(ReportPagesProperty, value);
            //Update some other properties associated with the control (Total Page Numbers, etc.)
        }
    }

    private static void ReportPagesChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs eventArgs)
    {
        var newColl = (INotifyCollectionChanged)eventArgs.NewValue;
        if (newColl != null)
            newColl.CollectionChanged += ReportPages_CollectionChanged;

        var oldColl = (INotifyCollectionChanged)eventArgs.OldValue;
        if (oldColl != null)
            oldColl.CollectionChanged -= ReportPages_CollectionChanged;
    }

    private static void ReportPages_CollectionChanged(object sender, NotifyCollectionChangedEventArgs eventArgs)
    {
        var newPages = (IList<ReportPage>) sender;

        //Updates properties of the Report control.
        _thisReport.ActivePage = newPages[0];
        _thisReport.TotalPageNumber = newPages.Count;

    }
}
公共部分类报告:UserControl,INotifyPropertyChanged
{
私有静态报告_thisReport;
公开报告(
{
初始化组件();
ReportPages=新的ObservableCollection();
_这个报告=这个;
}
公共静态只读从属属性报告页面属性=
DependencyProperty.Register(“ReportPages”、typeof(IList)、typeof(Report)、new FrameworkPropertyMetadata(ReportPagesChanged));
公共IList报告页
{
get=>(IList)GetValue(ReportPagesProperty);
设置
{
设置值(ReportPagesProperty,value);
//更新与控件关联的一些其他属性(总页码等)
}
}
私有静态无效报告页面更改(DependencyObject DependencyObject,DependencyPropertyChangedEventArgs)
{
var newColl=(INotifyCollectionChanged)eventArgs.NewValue;
if(newColl!=null)
newColl.CollectionChanged+=报告页面\u CollectionChanged;
var oldColl=(INotifyCollectionChanged)eventArgs.OldValue;
如果(oldColl!=null)
oldColl.CollectionChanged-=报告页面\u CollectionChanged;
}
私有静态void ReportPages\u CollectionChanged(对象发送方,NotifyCollectionChangedEventArgs)
{
var newPages=(IList)发送方;
//更新报表控件的属性。
_thisReport.ActivePage=新页面[0];
_thisReport.TotalPageNumber=newPages.Count;
}
}
我不能说这是否“正确”,但它是有效的。如果有人有更好的答案,我会改变答案