簡體   English   中英

如何將 datacontext 設置為 UserControl 的屬性?

[英]How can I set the datacontext to property of a UserControl?

具有此結構和 combobox:

public abstract class A: UserControl
{
     public string MachineName { get; protected set; }
     ...
}

public partial class MainWindow : Window
{
     private List<A> m_listA = new List<A>();

     public MainPanel()
     {
        InitializeComponent();
        DataContext = this;
     
        cbMachines.ItemsSource = m_listA;
        cbMachines.SelectedIndex = 0;
        cbMachines.DisplayMemberPath = "MachineName";
     }
}

如果我執行它,我將完美填充 combobox 的元素列表,但所選元素為空並引發綁定錯誤:

System.Windows.Data Error: 40 : BindingExpression path error: 'Name' property not found on 'object' 
''Grid' (Name='')'. BindingExpression:Path=Name; DataItem='Grid' (Name=''); target element is 
'TextBlock' (Name=''); target property is 'Text' (type 'String')

看來,它將“A”主控件的網格作為數據上下文似乎將主控件作為數據上下文,但我需要用戶控件作為數據上下文。

我怎樣才能做到這一點?

默認ComboBox模板中對應的區域是這樣的:

<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}" ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}" Content="{TemplateBinding SelectionBoxItem}" ContentStringFormat="{TemplateBinding SelectionBoxItemStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" IsHitTestVisible="false" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>

在此視覺效果中,您無法設置 SelectionBoxItemTemplate、SelectionBoxItem、SelectionBoxItemStringFormat,因為它們是只讀的。

根據.NET 源代碼(Combobox.cs UpdateSelectionBoxItem 方法)檢查當前項目是否為 ContentControl。 如果是,則將 Content 作為 SelectionBoxItem; ContentTemplate 作為 SelectionBoxItemTemplate 和 ContentStringFormat 作為 SelectionBoxItemStringFormat。

由於 UserControl 派生自 ContentControl; 您可以通過為 class A 設置 ContentTemplate 來實現,如下所示:

<UserControl.ContentTemplate>
    <DataTemplate>
        <TextBlock Text="{Binding Parent.MachineName}" />
    </DataTemplate>
</UserControl.ContentTemplate>

或者您可以使用 ComboBox 的自定義模板來分配如下內容:

Content="{Binding SelectedItem.MachineName, RelativeSource={RelativeSource Mode=TemplatedParent}}"

要獲取默認 combobox 模板,請使用此.

或者你可以在后面的代碼上做到這一點:

cbMachines.ApplyTemplate();
var contentPresenter = cbMachines.Template.FindName("contentPresenter", cbMachines) as ContentPresenter;
System.Windows.Data.BindingOperations.SetBinding(contentPresenter, ContentPresenter.ContentProperty, new Binding("SelectedItem.MachineName") { Source = cbMachines });
contentPresenter.ContentTemplateSelector = null;

恐怕沒有更簡單的方法了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM