简体   繁体   English

如何将依赖属性绑定到 UserControl 中的 DataGridComboBoxColumn?

[英]How to bind dependency property to DataGridComboBoxColumn in UserControl?

The XAML of my UserControl with name "Clinical_Protocol":我的用户控件的 XAML 名称为“Clinical_Protocol”:

<Grid>
        <DataGrid Name="ClinicalProtocolDataGrid"
                  ItemsSource="{Binding DataGridItems, ElementName=Clinical_Protocol}"
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridComboBoxColumn Header="Structure ID"
                                        ItemsSource="{Binding ComboBoxItems, ElementName=Clinical_Protocol, Mode=TwoWay}"
                                        SelectedItemBinding="{Binding SelectedStructureId, Mode=TwoWay}"
                                        />
                <DataGridTextColumn Header="RT ROI Type Code" 
                                    Binding="{Binding RtRoiInterpretedTypeCode}"/>
                <DataGridTextColumn Header="RT ROI Type Description"
                                    Binding="{Binding RtRoiInterpretedTypeDescription}"/>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>

The dependency property for ItemsSource of the DataGrid in the code behind:后面代码中DataGrid的ItemsSource的依赖属性:

internal ObservableCollection<ClinicalProtocolDataGridItem> DataGridItems
{
    get { return (ObservableCollection<ClinicalProtocolDataGridItem>)GetValue(DataGridItemsProperty); }
    set { SetValue(DataGridItemsProperty, value); }
}

internal static readonly DependencyProperty DataGridItemsProperty =
            DependencyProperty.Register("DataGridItems", typeof(ObservableCollection<ClinicalProtocolDataGridItem>),
                typeof(ClinicalProtocolView), new PropertyMetadata(null, DataGridItemsPropertyChangedCallback));

private static void DataGridItemsPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = (ClinicalProtocolView)d;
    control.DataGridItems = (ObservableCollection<ClinicalProtocolDataGridItem>)e.NewValue;
}

The according ClinicalProtocolDataGridItem class:根据ClinicalProtocolDataGridItem class:

public class ClinicalProtocolDataGridItem
{
    public string RtRoiInterpretedTypeCode { get; }
    public string RtRoiInterpretedTypeDescription { get; }
    public object SelectedStructureId { get; set; }

    public ClinicalProtocolDataGridItem(string rtRoiInterpretedTypeCode, string rtRoiInterpretedTypeDescription)
    {
        RtRoiInterpretedTypeCode = rtRoiInterpretedTypeCode ??
                                       throw new ArgumentNullException(nameof(rtRoiInterpretedTypeCode));
        RtRoiInterpretedTypeDescription = rtRoiInterpretedTypeDescription ??
                                              throw new ArgumentNullException(nameof(rtRoiInterpretedTypeDescription));
    }
}

And finally the dependency property ComboBoxItems :最后是依赖属性ComboBoxItems

public ObservableCollection<ComboBoxItem> ComboBoxItems
{
    get { return (ObservableCollection<ComboBoxItem>)GetValue(ComboBoxItemsProperty); }
    set { SetValue(ComboBoxItemsProperty, value); }
}

public static readonly DependencyProperty ComboBoxItemsProperty =
    DependencyProperty.Register("ComboBoxItems", typeof(ObservableCollection<ComboBoxItem>),
        typeof(ClinicalProtocolView), new PropertyMetadata(new ObservableCollection<ComboBoxItem>(),
                    PropertyChangedCallback));

private static void PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = (ClinicalProtocolView)d;
    control.ComboBoxItems = (ObservableCollection<ComboBoxItem>)e.NewValue;
}

I try to populate both dependency properties with the following:我尝试使用以下内容填充两个依赖属性:

private void AddSomeComboBoxItems()
{
    ComboBoxItems = new ObservableCollection<ComboBoxItem>
    {
        new ComboBoxItem(){Content = "S1",  HorizontalContentAlignment = HorizontalAlignment.Center, VerticalContentAlignment = VerticalAlignment.Center},
        new ComboBoxItem(){Content = "S2",  HorizontalContentAlignment = HorizontalAlignment.Center, VerticalContentAlignment = VerticalAlignment.Center},
        new ComboBoxItem(){Content = "S3",  HorizontalContentAlignment = HorizontalAlignment.Center, VerticalContentAlignment = VerticalAlignment.Center},
}

private void AddSomeRows()
{
    var items = new List<ClinicalProtocolDataGridItem>
    {
        new ClinicalProtocolDataGridItem("PTV", "Description of PTV, and it is a very long description!"),
        new ClinicalProtocolDataGridItem("OAR", "Description of OAR, and it is a very long description!"),
    };

    DataGridItems = new ObservableCollection<ClinicalProtocolDataGridItem>(items);
}

When I import it into a WPF application I get the following:当我将其导入 WPF 应用程序时,我得到以下信息:

组合框示例图片

And the error message: DataGridComboBoxColumn.ItemsSource IEnumerable Cannot find governing FrameworkElement or FrameworkContentElement for target element.错误消息: DataGridComboBoxColumn.ItemsSource IEnumerable Cannot find governing FrameworkElement or FrameworkContentElement for target element. 错误信息

Microsoft documentation says that it is possible to bind a collection of ComboBoxItem . Microsoft 文档说可以绑定ComboBoxItem的集合。 What am I missing?我错过了什么? I don't want to have a static resource, because the combo box items might change during runtime.我不想拥有 static 资源,因为组合框项目可能会在运行时发生变化。

The DataGridColumn is a simple DependencyObject, not a UI element. DataGridColumn 是一个简单的 DependencyObject,而不是 UI 元素。 It is not embedded in the visual tree and cannot get values from it.它没有嵌入到可视化树中,无法从中获取值。 The ElementName and FindAncestor bindings will not work in it. ElementName 和 FindAncestor 绑定在其中不起作用。

You need to get the collection into a static resource and only then get it from there for the DataGridColumn.您需要将集合放入 static 资源中,然后才从那里为 DataGridColumn 获取它。

<DataGrid Name="ClinicalProtocolDataGrid"
          ItemsSource="{Binding DataGridItems, ElementName=Clinical_Protocol}"
          AutoGenerateColumns="False">
    <FrameworkElement.Resources>
        <!--Using a CollectionViewSource as a proxy to create a "static link".-->
        <CollectionViewSource
            x:Key="comboBoxItems"
            Source="{Binding ComboBoxItems, ElementName=Clinical_Protocol}"/>
    </FrameworkElement.Resources>
    <DataGrid.Columns>
        <DataGridComboBoxColumn
            Header="Structure ID"
            ItemsSource="{Binding Source={StaticResource comboBoxItems}}"
            SelectedItemBinding="{Binding SelectedStructureId, Mode=TwoWay}"/>

PS Please note my comment on your question. PS请注意我对你的问题的评论。 I explain there why even after a successful binding to such a source, the ComboBoxs may still work incorrectly.我在那里解释了为什么即使在成功绑定到这样的源之后,ComboBox 仍可能无法正常工作。

Remove dependency property ComboBoxItems you don't need it, but add to the code behind a data provider method for your combo boxes:删除不需要的依赖属性ComboBoxItems ,但将其添加到组合框的数据提供程序方法背后的代码中:

public ObservableCollection<string> GetCbxSource()
{
    return new ObservableCollection<string>
    {
        "S1",
        "S2",
        "S3",
    };
}

Then in XAML you can declare a data provider and later use it like:然后在 XAML 中你可以声明一个数据提供者,然后像这样使用它:

<Grid>
    <Grid.Resources>
        <ObjectDataProvider x:Key="cbxData" MethodName="GetCbxSource" ObjectInstance="{x:Reference Clinical_Protocol}"/>
    </Grid.Resources>

    <DataGrid Name="ClinicalProtocolDataGrid"
                  ItemsSource="{Binding DataGridItems, ElementName=Clinical_Protocol}"
                  AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridComboBoxColumn Header="Structure ID"
                                        ItemsSource="{Binding Source= {StaticResource cbxData}}"
                                        SelectedItemBinding="{Binding SelectedStructureId, Mode=TwoWay}"
                                        />
            <DataGridTextColumn Header="RT ROI Type Code" 
                                    Binding="{Binding RtRoiInterpretedTypeCode}"/>
            <DataGridTextColumn Header="RT ROI Type Description"
                                    Binding="{Binding RtRoiInterpretedTypeDescription}"/>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在UserControl中绑定集合依赖项属性 - How to bind collection dependency property in UserControl 无法绑定用户控件的依赖项属性 - Unable to bind dependency property of usercontrol 在ItemControl中具有依赖项属性的UserControl:如何将ItemSource的元素绑定到UserControl的x:Name? - UserControl with Dependency Property inside an ItemsControl: how to Bind element of ItemSource to x:Name of UserControl? 如何将用户控件属性绑定到列表框 - How to bind a usercontrol property to Listbox WPF如何绑定用户控件属性 - wpf how to bind usercontrol property 如何验证 UserControl 上的依赖项属性? - How to validate a dependency property on a UserControl? 如何使用Style将子UserControl的Dependency属性绑定到宿主元素的视图模型的属性? - How to bind a child `UserControl`'s Dependency Property, using `Style`, to a property of the host element's view-model? 如何将WPF DataGridComboBoxColumn绑定到ViewModel属性? - How can I bind WPF DataGridComboBoxColumn to ViewModel Property? UserControl:如何转换依赖项属性并绑定到结果 - UserControl: how to convert dependency properties and bind to the result 如何将一个用户控件的视图模型中的属性绑定到另一个用户控件中的属性 - How to bind a property in the view model of a usercontrol to a property in another usercontrol
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM