简体   繁体   中英

C# How to edit cell value in gridview?

I have a gridview shown as below in XAML

<ListView x:Name="listTasks">
        <ListView.View>
            <GridView x:Name="gridTasks">
                <GridViewColumn Header="ID" HeaderStringFormat="Lowercase" Width ="26" DisplayMemberBinding="{Binding id}"/>
                <GridViewColumn Header="Something" Width="113" DisplayMemberBinding="{Binding something}"/>
                <GridViewColumn Header="State" Width="179" DisplayMemberBinding="{Binding currentState}"/>
            </GridView>
        </ListView.View>
    </ListView>

and i have a button which adds to this gridview using the below

m.myList.Add(new mylistview.myitems
        {
            id = m.id,
            something= m.something,
            currentState = m.currentState,
        });

This button works perfectly by adding the row into the gridview . However I would like to modify theCurrentState using a method that is running. How would I locate for example, ID = "8" and then modify theCurrentState for that row?

UPDATED CODE SHOWN I've now replaced my list<Task> with ObservableCollection and managed to get it to add to my listview when I click onto my button . However, I am struggling to implement the iNotifyPropertyChanged into my code and getting it to work correctly... Below is my listview class

public class mylistview : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private string _currentState;
    public string currentState
    {
        get { return _currentState; }
        set
        {
            _currentState = value;
            OnPropertyChanged();
        }
    }

    public ObservableCollection<myitems> _myList = new ObservableCollection<myitems>();
    public ObservableCollection<myitems> myList
    {
        get { return _myList; }
    }

    private static int _id = 0; 

    public class myitems
    {
        public int id { get; set; }
        public string something{ get; set; }
        public string currentState { get; set; }
    }

    public int id
    {
        get { return _id; }
        set { _id = value; }
    }
}

Maybe with

listOfTasks.Items.Cast<ListViewItem>().First(item => item.ID == "8").theCurrentState = newState;
//I'm not sure about the Cast stuff, because I don't know what types the ListView uses for its items

Of course you could iterate through the items with a loop and check manually for the ID as well.

So I see you're using data bindings already, that's good. But your question makes me think you haven't quite grasped everything it can do for you yet.

My recommendation would be to forget about adding items directly to listOfTasks.Items . Instead you should make an ObservableCollection to hold that list and bind the listOfTasks to it. Like so:

ObservableCollection tasks = new ObservableCollection<mylistview.myitems>();
ListOfTasks.ItemsSource = tasks;

With that binding in place you should be able to simply add new items to the tasks list when they click your button:

tasks.Add(new mylistview.myitems
    {
        id = theId,
        something= something,
        currentState = theCurrentState,
    });

and it should automatically update the GUI. The last step is to make sure that the class mylistview.myitems implements INotifyPropertyChanged . This is easier than it sounds; you just need to have it trigger an event any time the property is set. Something like so:

public class exampleProperties: INotifyPropertyChanged
{
    //this is the event you have to emit
    public event PropertyChangedEventHandler PropertyChanged;

    //This is a convenience function to trigger the event.
    //The CallerMemberName part will automatically figure out 
    //the name of the property you called from if propertyName == ""
    protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName);
        }
    }

    //Any time this property is set it will trigger the event
    private string _currentState = "";
    public string currentState
    {
        get { return _currentState; }
        set
        {
            if (_currentState != value)
            {
                _currentState = value;
                OnPropertyChanged();
            }
        }
    }
}

Now that the gridview is bound to an ObservableCollection and the items held in that collection can notify interested GUI controls that their properties have changed, you should simply be able to update the GUI simply by changing the appropriate item in the collection.

And here's an example of a form that uses the whole technique: https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).asp

edit

I forgot that you specifically need to bind to the ItemSource property of the ListView. The way I have done it in the past is to set ItemsSource={binding} in the ListView's xaml and then assign an ObservableCollection to ListView.DataContext . However I have found an easier way and updated the original post with it. Here's a reference: http://www.wpf-tutorial.com/listview-control/listview-with-gridview/

Edit 2

Aha, you're adding the iPropertyChangedNotify to the wrong thing. It goes on the myitems class like so:

public class myitems : iNotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([System.Runtime.CompilerServices.CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private int _id;
    public int id 
    { 
        get { return _id; }
        set
        {
            _id = value;
            OnPropertyChanged();
        }
    }

    public string something{ get; set; }
    public string currentState { get; set; }
}

I leave updating the current state and something properties as an excersize. They also need to trigger the OnPropertyChanged event when their value is set.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM