2

I have some XAML code that makes me mad. It started all with adding a dummy Item for a not referenced value.

For this I had to implement a CollectionViewSource and a CompositeCollection. Now I can't select the first Combobox Item, it appears but I cannot select it, because I set the DisplayMemberPath in XAML (I guess so). Also the separator looks not as expected.

Let me show you:


screenshot


If I don't set the XAML DisplayMemberPath, I can use the Dummy Item but the bound ones are displayed incorrect:

screenshot

XAML:

<ComboBox x:Name="G_cb_content_zuordnung" 
          Margin="165,0,0,0" 
          Grid.Row="1" 
          SelectedIndex="0"
          VerticalAlignment="Top"
          DisplayMemberPath="PartnerID"
          HorizontalAlignment="Left" 
          Width="119">
    <ComboBox.Resources>
        <CollectionViewSource x:Key="ComboCollection" Source="{Binding Path=mySelectedItem.Stammkinder}" />
    </ComboBox.Resources>
    <ComboBox.ItemsSource>
        <CompositeCollection>
            <ComboBoxItem Content="Ohne Stammnummer" Name="NoPID" />
            <Separator />
            <CollectionContainer Collection="{Binding Source={StaticResource ComboCollection}, Mode=OneWay}" />
        </CompositeCollection>
    </ComboBox.ItemsSource>
</ComboBox>

All I need is a dummy / placeholder combobox item that gets shown on top of the ObservableCollection<myClass>. Is my way of thinking wrong? Is there a smarter solution? Do I miss something in my solution?

dymanoid
  • 14,771
  • 4
  • 36
  • 64
kurdy
  • 441
  • 4
  • 15
  • I'm not sure what purpose the "dummy item" serves, but it looks like you're trying to get the combo box to operate differently than it is designed. That's often very hard. Creating UI in general is often hard. I'd suggest you either create a UserControl with logic in the codebehind to manage the dummy item (UI logic goes in the codebehind, don't think that's not mvvm), drop the concept altogether, or find a different combo control out there that behaves the way you want. –  May 03 '18 at 15:27
  • 1
    It is linked with my Viewmodel in the Background and If I choose a value, an existing value should be modified or overwritten. If the dummy field is choosen, it should lead to the creation of a new object in my Viewmodel. In the end it is a straightforward "switch" - not that uncommon. – kurdy May 03 '18 at 15:38

1 Answers1

3

Use your second approach and define a DataTemplate for the items explicitly, rather than using the DisplayMemberPath property:

<ComboBox xmlns:o="clr-namespace:APP.GLN_Organisator.Objects">
    <ComboBox.Resources>
        <CollectionViewSource x:Key="ComboCollection"
                              Source="{Binding Path=mySelectedItem.Stammkinder}" />

        <!-- Define a DataTemplate here -->
        <DataTemplate DataType="{x:Type o:ChildPartner}">
            <TextBlock Text="{Binding PartnerID}"/>
        </DataTemplate>

    </ComboBox.Resources>
    <ComboBox.ItemsSource>
        <CompositeCollection>
            <ComboBoxItem Content="Ohne Stammnummer" Name="NoPID" />
            <Separator />
            <CollectionContainer Collection="{Binding Source={StaticResource ComboCollection}}" />
        </CompositeCollection>
    </ComboBox.ItemsSource>
</ComboBox>

With a DataTemplate, you tell WPF how you want to display your items. If you don't provide any DataTemplate and don't set the DisplayMemberPath property value, WPF falls back to the simple ToString() call for displaying your items. That's why you see these type strings instead of your items.

dymanoid
  • 14,771
  • 4
  • 36
  • 64
  • I will give it a try and report back once I am done. Thanks in advance. – kurdy May 03 '18 at 15:39
  • Your appproach worked flawless. I think I also understood what is happening. You define a namespace in the XAML Element to address the object structure which is used in my Viewmodel in XAML. And the datatemplate itself overloads the binding between the object and the GUI element? This is huge, love this feature, because I often work with custom classes! Then overload the Text property of the GUI-Element with the reference to the property PartnerID in my object ChildPartner? I hope I got this right. Thank you so much! – kurdy May 04 '18 at 09:01
  • 1
    You're no completely right in your guess. This feature is called 'data templating' and it is a core concept of WPF, it enables using the MVVM pattern in a very convenient way. You should [read more about it](https://learn.microsoft.com/en-us/dotnet/framework/wpf/data/data-templating-overview). – dymanoid May 04 '18 at 09:06
  • It is bookmarked, and next time I will do my homework before asking :) – kurdy May 04 '18 at 09:09