簡體   English   中英

WPF組合框中所選項目的模板與組合集合中的項目的模板不同

[英]Different template for selected item in WPF combobox than items in composite collection

我有一個包含以下內容的復合集合:

  • 內容為“選擇供應商”的組合框項目
  • 具有綁定到組合框cmbVendor的Vendor對象的集合的容器

當從組合框中選擇一個供應商時,將調用ToString()方法。 但是,我想顯示所選Vendor對象的屬性Name的值。 在此處輸入圖片說明 在此處輸入圖片說明

設置組合框屬性DisplayMemberPath='Name'可以,但是加載時不再顯示“選擇供應商”,這是不希望的。

筆記:

  • 有時從代碼隱藏中選擇一個Vendor對象
  • 由於其他原因,我無法覆蓋Vendor對象的ToString()方法

有什么建議么?

XAML

<UserControl.Resources>
    <converters:VendorConverter x:Key='VendorConverter' />
    <CollectionViewSource x:Key='VendorsCollection'
                          Source='{Binding Vendors}'>
    </CollectionViewSource>
  </UserControl.Resources>
  <Grid>
    <ComboBox Name='cmbVendor'
              SelectedItem='{Binding Vendor, Converter={StaticResource VendorConverter}, Mode=TwoWay}'
              IsSynchronizedWithCurrentItem='True'
              IsEditable='True'
              Width='{DynamicResource VendorCmbWidth}'>
      <!--Make sure "Select a vendor" is selected-->
      <i:Interaction.Behaviors>
        <behaviour:SelectFirstItemBehavior />
      </i:Interaction.Behaviors>
      <ComboBox.Resources>
        <DataTemplate DataType='{x:Type objects:Vendor}'>
          <StackPanel Orientation='Horizontal'>
            <TextBlock Text='{Binding Name}' />
          </StackPanel>
        </DataTemplate>
        <DataTemplate DataType='{x:Type system:String}'>
          <StackPanel Orientation='Horizontal'>
            <TextBlock Text='{Binding }' />
          </StackPanel>
        </DataTemplate>
      </ComboBox.Resources>
      <ComboBox.ItemsSource>
        <CompositeCollection>
          <ComboBoxItem Content='Select a vendor' />
          <CollectionContainer Collection='{Binding Source={StaticResource VendorsCollection}}' />
        </CompositeCollection>
      </ComboBox.ItemsSource>

    </ComboBox>
  </Grid>
</UserControl>

VendorConverter

internal class VendorConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var vendor = value as Vendor;
            if (vendor != null)
            {
                return vendor;
            }
            return null;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var comboboxItem = value as ComboBoxItem;
            if (comboboxItem != null)
            {
                return null;
            }

            var vendor = value as Vendor;
            if (vendor != null)
            {
                return vendor;
            }

            return null;
        }
    }

行為

internal class SelectFirstItemBehavior : Behavior<ComboBox>
    {
        protected override void OnAttached()
        {
            AssociatedObject.SelectionChanged += AssociatedObject_SelectionChanged;
        }

        protected override void OnDetaching()
        {
            AssociatedObject.SelectionChanged -= AssociatedObject_SelectionChanged;
            base.OnDetaching();
        }

        private void AssociatedObject_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            var combobox = sender as ComboBox;
            if (combobox != null && combobox.SelectedIndex == -1)
            {
                combobox.SelectedIndex = 0;
            }
        }
    }

方法1

您應該能夠將正常項目的TextSearch.TextPath="Name"和直接分配給特殊項目的TextSearch.Text="Select a vendor"組合在一起:

<ComboBox
    IsEditable="True"
    TextSearch.TextPath="Name">
...

<CompositeCollection>
    <ComboBoxItem Content='Select a vendor' TextSearch.Text="Select a vendor" />
    <CollectionContainer Collection='{Binding Source={StaticResource VendorsCollection}}' />
</CompositeCollection>

方法2

只要不選擇任何內容,僅顯示視覺提示文本:

<ComboBox
    ItemsSource="{Binding Source={StaticResource VendorsCollection}}"
    IsEditable="True">
    <ComboBox.Style>
        <Style TargetType="ComboBox">
            <Style.Resources>
                <VisualBrush x:Key="hintText" x:Shared="False"  AlignmentX="Left" Stretch="None">
                    <VisualBrush.Visual>
                        <Grid Background="White">
                            <TextBlock Margin="4 3" Text="Select a vendor"/>
                        </Grid>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Style.Resources>
            <Style.Triggers>
                <Trigger Property="Text" Value="">
                    <Setter Property="Background" Value="{StaticResource hintText}"/>
                </Trigger>
                <Trigger Property="Text" Value="{x:Null}">
                    <Setter Property="Background" Value="{StaticResource hintText}"/>
                </Trigger>
            </Style.Triggers>
        </Style>
    </ComboBox.Style>
</ComboBox>

這樣,您可以使項目集合中沒有多余的條目,並為您的實際項目使用TextSearch.TextPath和類似的屬性。

暫無
暫無

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

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