2

I am trying to bind a textbox inside itemtemplate of my listview. As itemssource, I am using ObservableCollection. I have tried binding itemtemplate to datacontext itself by {Binding},yet it gives me InvalidOperationException. Here is the related snippet

<ListView Name="listOrder" ItemsSource="{Binding OrderBys,UpdateSourceTrigger=PropertyChanged}" HorizontalContentAlignment="Stretch">
                            <ListView.ContextMenu>
                                <ContextMenu>
                                    <MenuItem Name="AddOrder" Header="Sıra Ekle" Click="AddOrder_Click" />
                                </ContextMenu>
                            </ListView.ContextMenu>
                            <ListView.ItemTemplate>
                                <DataTemplate>
                                    <TextBox FontSize="10" Text="{Binding}"></TextBox>
                                </DataTemplate>
                            </ListView.ItemTemplate>
                        </ListView>

Here is the related part from the ViewModel

public class ViewModel_ReportDesigner : ViewModelBase
{

    //Tables
    public List<string> Tables
    {
        get
        {
            Reporting.ReportUtils rr = new Reporting.ReportUtils();
            return rr.GetChildList("IGAEntities");
        }
    }

    private string _selectedTable;
    public string SelectedTable {
        get
        {
            return _selectedTable;
        }
        set
        {
            _selectedTable = value;
            RaisePropertyChangedEvent("SelectedTable");
            RaisePropertyChangedEvent("Fields");

        }
    }

    //Fields
    public ObservableCollection<string> Fields
    {
        get
        {
            Reporting.ReportUtils rr = new Reporting.ReportUtils();
            if (SelectedTable != null)
            {
                return new ObservableCollection<string>(rr.GetChildList(SelectedTable));
            }
            return null;
        }
    }


    //Number of Fields
    private int _NumberOfFields;
    public int NumberOfFields
    {
        get
        {
            return _NumberOfFields;
        }
        set
        {
            _NumberOfFields = value;
            RaisePropertyChangedEvent("NumberOfFields");
        }
    }

    public ObservableCollection<ReportField> getEmptyFieldList()
    {
        ObservableCollection<ReportField> list = new ObservableCollection<ReportField>();
        for (int i = 1; i <= _NumberOfFields; i++)
        {
            list.Add(new ReportField("''", i.ToString()));
        }
        return list;
    }

    //Groups
    private List<string> _Groups;
    public List<string> Groups
    {
        get
        {
            if (_Groups == null)
            {
                _Groups = new List<string>();
            }
            return _Groups;
        }set
        {
            _Groups = value;
            RaisePropertyChangedEvent("Groups");
        }
    }
    //TableCreators
    private ObservableCollection<TableCreator> _TableCreators;
    public ObservableCollection<TableCreator> TableCreators
    {
        get
        {
            if (_TableCreators == null)
                _TableCreators = new ObservableCollection<TableCreator>();  
            return _TableCreators;
        }
        set
        {
            _TableCreators = value;
            RaisePropertyChangedEvent("TableCreators");
        }
    }

    private TableCreator _SelectedTableCreator;
    public TableCreator SelectedTableCreator
    {
        get
        {
            return _SelectedTableCreator;
        }
        set
        {
            _SelectedTableCreator = value;
            RaisePropertyChangedEvent("SelectedTableCreator");
        }
    }

    internal void RaiseChanged(string v)
    {
        RaisePropertyChangedEvent(v);
    }
}

Actually listview i am talking about is inside another listview. To make it all clear. When i add item to parent listview, I create an empty List and bind it to child listview. Then from context menu i add related elements like this

vm.SelectedTableCreator.OrderBys.Add("");
        vm.RaiseChanged("TableCreators");

Edit: Now i realized that my binding is correct, only problem is that textbox change event will not fire after i change the text inside the textbox.

Kemal
  • 96
  • 8

2 Answers2

1

If Your Binding is correct, you have to set the Binding Mode from your textbox to "TwoWay"

Like:

 <TextBox FontSize="10" Text="{Binding bla, Mode=TwoWay}"></TextBox>

Because, if you don´t set a Mode, the standard Mode is Mode = OneTime

Here are the different Modes if you don´t know them.

Community
  • 1
  • 1
FoldFence
  • 2,674
  • 4
  • 33
  • 57
  • Unfortunately, setting mode "TwoWay" did not resolve my problem. I think somehow textbox editting event is never ending even though I had set "UpdateSourceTrigger=PropertyChanged" – Kemal May 23 '16 at 11:57
  • Can you debug and set a breakpoint to the setter of your textbox, so you can check if it set anything after changing the text ? And I havn´t see it but you also know that the observable collection is only fire onproperty changed, when you add or deleting an object – FoldFence May 23 '16 at 12:15
1

Now i realized that my binding is correct, only problem is that textbox change event will not fire after i change the text inside the textbox.

then you should implement INotifyPropertyChanged in your model class:

public class TableCreator:INotifyPropertyChanged
{

    private string yourVariable;
    public string YourVariable
    {
        get { return YourVariable; }
        set {
            YourVariable =value;
            OnPropertyChanged("YourVariable");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

}

As MSDN says:

Cause INotifyPropertyChanged0 notifies clients(UI) that a property value has changed.

like in the following example:

public class Person:INotifyPropertyChanged
{
    public int IdPerson { get; set; }

    private string name;
    public string Name
    {
        get { return name; }
        set {
            name =value;
            OnPropertyChanged("Name");
        }
    }

    private string surname;
    public string SurName
    {
        get { return surname; }
        set
        {
            surname = value;
            OnPropertyChanged("SurName");
        }
    }        

    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

}
StepUp
  • 36,391
  • 15
  • 88
  • 148
  • @Kemal feel free to ask any question. If you feel that my reply helps to you, then you can mark my reply as an answer to simplify future search of other people. Please, read this http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – StepUp May 24 '16 at 06:42