【问题标题】:Easy way to add a Label to the WPF ComboBox control向 WPF ComboBox 控件添加标签的简单方法
【发布时间】:2012-09-25 20:20:40
【问题描述】:

此代码在我的应用程序中越来越常见:

<StackPanel Orientation="Vertical">
    <Label Content="_ComboBox Caption" 
           Target="comboBox" 
           Margin="0" 
           Padding="5,5,5,1" />

    <ComboBox  x:Name="comboBox"
                Width="72"
                Margin="5,0,5,5"
                Padding="5,1,5,5"
                SelectedItem="{Binding ComboSelectedItem}"
                ItemsSource="{Binding ComboSourceList}" />
</StackPanel>

它为我呈现了一个带字幕的组合框。

我想让我成为一个自定义控件,它是一个 ComboBox,它公开标签的内容,然后设置其他属性。可以这样使用的东西:

<Controls:CaptionedComboBox  x:Name="comboBox"
                             Width="72"
                             LabelContent="_ComboBox Caption"
                             SelectedItem="{Binding ComboSelectedItem}"
                             ItemsSource="{Binding ComboSourceList}" />

但是,我考虑制作自定义控件,并且需要令人生畏的样式数量。

有没有办法接受我上面的内容并最终做这样的事情?

<StackPanel Orientation="Vertical">
    <Label Content="{Binding TemplateLabelContent}" 
           Target="{Binding ControlName}" 
           Margin="0" 
           Padding="5,5,5,1" />

    <InheritedComboBoxStuff/>

</StackPanel>

我知道那行不通。但我的观点是,我必须重新设置整个 ComboBox 的样式只是为了在它上面添加一个标签,这似乎很愚蠢。

【问题讨论】:

  • 你看过UserControls吗?只需设置 DP 属性即可。
  • @HenkHolterman - 那里的问题(据我了解)是我必须重新公开 ComboBox 的所有属性。如果是这样,我想我只能选择两害相权取其轻。
  • 只是你没有提到所有选项。 ControlTemplate、UserCONtrol 和 CustomControl。我认为@Sebastian 的回答值得一试。

标签: c# .net wpf custom-controls


【解决方案1】:

您可以为此制作模板

  <ControlTemplate x:Key="ComboWithHeader" TargetType="ContentControl">
        <StackPanel Orientation="Vertical">
            <Label Margin="0"
                   Content="{Binding ComboBoxHeader}"
                   DataContext="{TemplateBinding DataContext}"
                   Padding="5,5,5,1"
                   Target="comboBox" />

            <ComboBox x:Name="comboBox"
                      Width="72"
                      Margin="5,0,5,5"
                      DataContext="{TemplateBinding DataContext}"
                      ItemsSource="{Binding ComboSourceList}"
                      Padding="5,1,5,5"
                      SelectedItem="{Binding ComboSelectedItem}" />
        </StackPanel>
    </ControlTemplate>

然后,每当您想使用带有标题的组合时,只需使用

<ContentControl Template="{StaticResource ComboWithHeader}" DataContext="{Binding ComboBoxViewModel}" />

【讨论】:

  • 这种方法可以与它的两个实例一起使用(具有不同的标签)吗?似乎这只会一遍又一遍地制作相同的组合框/标题组合。有没有办法在 ContentControl 级别绑定 Label.Content、ComboBox.SelecteItem 和 ComboBox.ItemsSource?
  • 我假设您使用 MVVM 模式,ContentControl 的 datacontext 将确定 itemsource 和组合框的选定项。标签内容也应该取自 ViewModel。 ComboBoxViewModel 的实例应包含属性 { ComboSourceList, ComboSelectedItem, ComboBoxHeader}。因此,您可以根据作为 DataContext 传递的视图模型来区分控件中的项目
  • 好的,这会起作用。这不是我想要的,但它会起作用。 (必须为我的 ComboBoxHeader 的每个实例创建一个单独的 ViewModel 有点冗长。)
  • 如果你不喜欢从视图模型传递组合头,只需将标签内容绑定到内容控件的内容:) 并使用它
【解决方案2】:

非常基本但非常简单,您还可以创建一个 UserControl,然后将您的控件嵌入到您想要的任何位置。 例如

<UserControl x:Class="xxx.View.TestResultsGraph"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" 
         MinHeight="50"
         d:DesignHeight="50" d:DesignWidth="300" >

    <Canvas Name="canvas" >
        <Polygon x:Name="SuccessShape" Fill="#FFF0FFF0" SnapsToDevicePixels="True"   />
        <Polyline x:Name="SuccessLine" Stroke="Green"    StrokeThickness="0.5" SnapsToDevicePixels="True"   />
        <Polygon x:Name="FailShape" Fill="#FFFFF0F0" SnapsToDevicePixels="True"   />
        <Polyline x:Name="FailLine" Stroke="Red"  StrokeThickness="0.5" SnapsToDevicePixels="True"      />
        <Polygon x:Name="PendingShape" Fill="#FFFFF0E0" SnapsToDevicePixels="True"   />
        <Polyline x:Name="PendingLine" Stroke="DarkOrange" StrokeThickness="0.5" SnapsToDevicePixels="True"    />
        <Line x:Name="xAxis" Stroke="Black" StrokeThickness="0.5" SnapsToDevicePixels="True"  />
        <Line x:Name="yAxis" Stroke="Black" StrokeThickness="0.5" SnapsToDevicePixels="True" />
    </Canvas>

【讨论】:

    猜你喜欢
    • 2016-12-17
    • 2019-03-13
    • 1970-01-01
    • 2012-04-10
    • 1970-01-01
    • 2017-08-13
    • 2011-11-07
    • 2022-07-29
    • 2014-06-13
    相关资源
    最近更新 更多