WPF中如何在用户控件中绑定集合属性

7

我有一个自定义的UserControl,其中包含自定义对象的集合。

public class Question : FrameworkElement
{
    public readonly static DependencyProperty FullNameProperty =
        DependencyProperty.Register("FullName", typeof(string), typeof(Question));

    public readonly static DependencyProperty ShortNameProperty =
        DependencyProperty.Register("ShortName", typeof(string), typeof(Question));

    public readonly static DependencyProperty RecOrderProperty =
        DependencyProperty.Register("RecOrder", typeof(int), typeof(Question));

    public readonly static DependencyProperty AnswerProperty =
        DependencyProperty.Register("Answer", typeof(string), typeof(Question));

    public string FullName
    {
        get { return (string)GetValue(FullNameProperty); }
        set { SetValue(NameProperty, value); }
    }

    public string ShortName
    {
        get { return (string)GetValue(ShortNameProperty); }
        set { SetValue(ShortNameProperty, value); }
    }

    public string Answer
    {
        get { return (string)GetValue(AnswerProperty); }
        set { SetValue(AnswerProperty, value); }
    }

    public int RecOrder
    {
        get { return (int)GetValue(RecOrderProperty); }
        set { SetValue(RecOrderProperty, value); }
    }
}

在我的控制代码后台,我有以下内容:
public readonly static DependencyProperty QuestionsProperty =
        DependencyProperty.Register("Questions", typeof(ObservableCollection<Question>), typeof(FormQuestionReportViewer), 
        new PropertyMetadata(new ObservableCollection<Question>()));


     public ObservableCollection<Question> Questions
     {
        get { return GetValue(QuestionsProperty) as ObservableCollection<Question>; }
        set { SetValue(QuestionsProperty, value); }
     }

在XAML标记中,我可以这样定义我的控件:

    <custom:CustomControl>
        <custom:CustomControl.Questions>
            <custom:Question FullName="smth text" ShortName="smth text" RecOrder="1" Answer="Yes" />
            <custom:Question FullName="smth text" ShortName="smth text" RecOrder="2" Answer="Yes" />
        </custom:CustomControl.Questions>          
    </custom:CustomControl>

它的功能很好,但我希望能像这样在XAML中绑定我的集合属性
    <custom:CustomControl>
        <custom:CustomControl.Questions Items="{binding Path=Questions}">
            <custom:Question FullName="{binding Name}" ShortName="{binding ShortName}" RecOrder="{binding RecOrder}" Answer={binding Answer}" /> 
        </custom:CustomControl.Questions>          
    </custom:CustomControl>

我该如何进行绑定?

从您的问题中不清楚应该从哪里获取要绑定到自定义控件的Questions属性的数据,您是只想展示问题还是将某个外部数据源绑定到CustomControl.Questions属性然后展示它们? - sll
数据应该来自一个 ViewModel 对象(其中包含具有相同字段的对象集合)。我的控件内部有 WinForms 控件。Wpf 控件应该从属性中获取数据并将其设置到 WinFormControl。 - roguepnz
1个回答

11
你需要暴露两个独立的属性,就像一个ItemsControl一样,它有一个Items和一个ItemsSource属性。看起来你想能够通过绑定显式地向集合中添加项。这种行为与ItemsControl不同,后者只允许你使用Items或ItemsSource属性,但不能同时使用。

然而,没有什么可以阻止你支持指定项目的两种方式,但这需要你付出更多的工作。

首先,你需要一个依赖属性,比如IEnumerable QuestionsSource,你可以将其绑定到:

public readonly static DependencyProperty QuestionsSourceProperty =
    DependencyProperty.Register("QuestionsSource",
        typeof(IEnumerable),
        typeof(FormQuestionReportViewer), 
        new PropertyMetadata(null));

 public IEnumerable QuestionsSource
 {
    get { return GetValue(QuestionsSourceProperty) as IEnumerable; }
    set { SetValue(QuestionsSourceProperty, value); }
 }

其次,您需要一个常规的CLR属性,例如ObservableCollection<Question> Questions,您可以明确地向其中添加项目:

private ObservableCollection<Question> questions = new ObservableCollection<Question>();
public ObservableCollection<Question> Questions
 {
    get { return questions; }
 }

那么你可以像这样使用这些属性:

<custom:CustomControl QuestionsSource="{Binding Path=Questions}">
    <custom:CustomControl.Questions>
        <custom:Question FullName="{Binding Name}" ShortName="{Binding ShortName}" RecOrder="{Binding RecOrder}" Answer={Binding Answer}" /> 
    </custom:CustomControl.Questions>          
</custom:CustomControl>

当你想要获取完整的项目列表时,额外的工作就会出现。您需要将这两个集合合并为一个单独的集合。这个统一的集合将被公开为第三个属性,该属性返回一个只读集合。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接