16

I have a ComboBox in a WPF application that is bound to an ObservableCollection of Department objects in a C# ViewModel class. I want to use the combo box to filter another collection by department (And indeed it works for that now) The problem is that I want to add an additional option "All" to the top of the list. Is there a correct way to do this. Making a fake department feels wrong in so many ways.

The ComboBox

<ComboBox ItemsSource="{Binding Path=Departments}" 
          SelectedValue="{Binding Path=DepartmentToShow , Mode=TwoWay}" />
Ahmad Mageed
  • 94,561
  • 19
  • 163
  • 174
Mike B
  • 2,592
  • 3
  • 33
  • 46

2 Answers2

23

You could use a CompositeCollection as the ItemsSource for the ComboBox to include the "All" option. You need to set the Collection property of the CollectionContainer to your "ObservableCollection of Department objects".

<ComboBox >
    <ComboBox.ItemsSource>
        <CompositeCollection>
            <ComboBoxItem>All</ComboBoxItem>
            <CollectionContainer x:Name="departmentCollection"/>
        </CompositeCollection>
    </ComboBox.ItemsSource>
</ComboBox>

Not sure if this will be suitable for your filtering situation however...

Simon Fox
  • 10,409
  • 7
  • 60
  • 81
  • 1
    +1 Wow as an experienced WPF programmer I was not even aware of `CompositeCollection`! There are all sorts of workarounds for this when searching the internet, but none mention this! Incredible... – Aviad P. Jan 28 '10 at 07:11
  • Yeah when i read this i was amazed. I have been doing some looking into it this morning and i think it will do the trick. Right now the filtering is done in the building of the Linq query so I am thinking I can test for 'All' and if that is not selected iterate the peopleCollection. In the future I was planning on refactoring and using a CollectionViewSource to filter the view without requerying; I'm not sure how that would work but for this question I have my answer. Thank You! – Mike B Jan 28 '10 at 16:01
  • 1
    @Aviad yes it is a nice solution, one thing that does suck a bit is that you can't bind to the Collection property via DataContext as CompositeCollection is not Freezable. This can be worked around by binding to a static resource... – Simon Fox Jan 28 '10 at 19:59
  • 2
    the solution to this question has a an example of how to bind in this manner http://stackoverflow.com/questions/1189052/why-is-compositecollection-not-freezable not particularly pretty IMO but does the trick... – Simon Fox Jan 28 '10 at 20:07
  • Adding a ComboBoxitem in this manner throws HorizontalContentAlignment and VerticalContentAlignment binding errors. Does anyone have a solution for this? – Julien Oct 21 '13 at 16:06
0

Suppose you have a ComboBox named MyCombo, an entity named MyEntity associated with a DomaineService named MyDomainService.

Do not forget

using System.ServiceModel.DomainServices.Client;

and of course the using working well with your Web site of your entity and DomainService

You call a Proc named :

void LoadEntities()
{
    MyDomainService_Context = new MyDomainService();
    EntityQuery<MyEntity > mQuery = null;

    mQuery = from q in _Context.GetMyDomainServiceQuery()
             select q;

    LoadOperation<MyEntity > loadOpLoadEntities = _Context.Load(mQuery, LoadOpLoadEntitiesCallBack, null);
}

Then in the CallBack function:

void LoadOpLoadEntitiesCallBack(LoadOperation<MyEntity> loadOperation)
{
    if (loadOperation.Entities.Count() > 0)
    {
        List<MyEntity> mList = new List<MyEntity>();
        MyEntity mE = new MyEntity();
        mE.Column1 = -1;
        mE.Column2 = "Default value";
        mList.Add(mE);

        for (int i = 0; i < loadOperation.Entities.Count(); i++)
        {
            mList.Add(loadOperation.Entities.ToList()[i]);
        }

        this.MyCombo.ItemsSource = mList.ToList();
    }
}
Carsten
  • 11,287
  • 7
  • 39
  • 62
  • This is a MVVM WPF app using Linq to SQL. The Composite COllection solution has been working quite well for a couple years but thanks for the additional input. – Mike B Apr 12 '13 at 16:43