Search code examples
c#wpfcomboboxbindingdatagrid

How to use Static Resource for WPF datagrid comboBox binding


I am developing WPF application with entity framework as well. But I DO NOT use MVVM I have a ENUM types, So I need to initialize the combo box item source with ALL enum types and select the value based on my Data. to simplify just consider binding a simple list to combo box. I have tired different ways but there is a problem I cant figure out.

<Page x:Class="Library.View.Reader"
  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" 
  xmlns:local="clr-namespace:Library.View"
  mc:Ignorable="d" 
  d:DesignHeight="300"
  Title="Reader" Width="900">


<Grid Margin="0,0,0,0">

    <DataGrid Name="grid_reader"    AutoGenerateColumns="True" HorizontalAlignment="Left" Height="126" Margin="23,20,0,0" VerticalAlignment="Top" Width="845" RowEditEnding="grid_reader_RowEditEnding" AutoGeneratingColumn="grid_reader_AutoGeneratingColumn">
        <DataGrid.Columns>

               <DataGridComboBoxColumn Header="Type"
                ItemsSource="{DynamicResource enumlist}}"
                DisplayMemberPath="Name"
                SelectedValuePath="Id"
                SelectedValueBinding="{Binding Type}"
        </DataGrid.Columns>
    </DataGrid>

</Grid>

I have tried DynamicResource ,StaticResource,Binding. None of them works!

  public partial class Reader : Page
  {
  public Reader() // Redaer is my page in xaml
    { 
        LibraryDataAccess.Model1 model = new Model1();
        List<LibraryDataAccess.Model.Reader> list = new List<LibraryDataAccess.Model.Reader>();
        list = model.Readers.ToList();
    public ObservableCollection<ReaderType> enumlist { get; set; }
 // initialize datagrid succefully Also enumlist = getEnumValues();
        enumlist = new ObservableCollection<ReaderType>();
        //enumlist = new List<LibraryDataAccess.EnumTypes.ReaderType>();
        typelist = Enum.GetValues(typeof      
        (LibraryDataAccess.EnumTypes.ReaderType))
        .Cast<LibraryDataAccess.EnumTypes.ReaderType>().Select(x => new ReaderType { Id = (int)x, Name = x.ToString() }).ToList();
        foreach (var item in typelist)
        {

            enumlist.Add(item);
        }
    grid_reader.ItemsSource = list;
    }

    public class ReaderType
    {
    public  int Id { get; set; }
    public   string Name { get; set; }
    }
 }

nothing is loaded into the Combo. What is the solution. Thanks

EDITED:

I am 99% sure that the problem is ItemSource of combo BUT:

I need the combo filled with enum values and the selected value is shown as given, suhc as Staff (which is in enum list with id 2) anyway the combo would not be filled at all. I am using this in a separate wpf Page.

I think the problem is in my data context related to combo box, i tried with sparated combo box even, with the binding mentioned above, but it does not work.

When I use AUTOGENERATED = true, the combo box would be created nicely with seleted value.


Solution

  • Finally I found a better and simpler answer for my question, let me share with you guys:

    We need to define a class as the dataSource of our combo box. So all of combo boxes must have these datas, and then based on a property which we set(from the data grids data source) combo box value must be selected and shown. Also we need to define a combo box resource at the top of the page, or window.

        <Page.Resources>
            <local:viewmodel x:Key="viewmodel"/>
        </Page.Resources>
    
    
        <Grid Margin="0,0,0,0">
    
        <DataGrid Name="grid_doc" AutoGenerateColumns="True" HorizontalAlignment="Left" Height="100" Margin="31,55,0,0" VerticalAlignment="Top" Width="636">
            <DataGrid.Columns>
                <DataGridComboBoxColumn Header="PublisherId"
                    ItemsSource="{StaticResource viewmodel}"
                                  SelectedValueBinding="{Binding PublisherId , UpdateSourceTrigger=PropertyChanged}"
                                  DisplayMemberPath="Value" 
                                  SelectedValuePath="Key">
                </DataGridComboBoxColumn>
            </DataGrid.Columns>
        </DataGrid>
        <ComboBox HorizontalAlignment="Left" Margin="130,193,0,0" VerticalAlignment="Top" Width="120"
            ItemsSource="{StaticResource viewmodel}"
                                  SelectedValue="{Binding PublisherId , UpdateSourceTrigger=PropertyChanged}"
                                  DisplayMemberPath="Value" 
                                  SelectedValuePath="Key">
        </ComboBox>
    
    </Grid>
    

    NOTE here, I used Key and Value for selected and display members. its important, even key and value are wrong. it MUST be Value and Key, with uppercase. I posted a simpler version, not enum members, it does not make any difference. you can create your list of enum members, and then add it into in your viewmodel class.It doesn't matter if your viewmodel class has other properties. just be sure to return an Enumerable data or inherit from a upper Enumerable class, as I did.

     public partial class Document : Page
    {
    
        LibraryDataAccess.Model1 model;
    
        List<LibraryDataAccess.Model.Document> list;
        public Document()
        {
            model = new Model1();
            list = new List<LibraryDataAccess.Model.Document>();
            list = model.Documents.ToList();
            InitializeComponent();
            list.Add(new LibraryDataAccess.Model.Document { Id = 1, PublisherId = 2, Title = "sdfs" });
            grid_doc.ItemsSource = list;
    
        }
    
        public class viewmodel : List<KeyValuePair<string,string>>
        {
    
        public viewmodel()
        {
    
            this.Add(new KeyValuePair<string, string>(1.ToString(), "s"));
            this.Add(new KeyValuePair<string, string>(2.ToString(), "t"));
        }
        }
    

    Thanks to previous answer and to these two links which helped me :

    binding

    static resource