简体   繁体   中英

WPF Listview + GridView - View not Updating

I have got a Listview Item with a Gridview Child, bound to a List of Objects. Below the Gridview I have got texboxes to edit the content of the Gridview (bound to the Gridview). I can add new content (which is displayed in the GridView). When i edit content, it is in fact edited (in the object list) but not displayed in the Gridview (the GridView does not seem to update)

xaml code:

<!-- ========= -->
<!-- root Grid -->
<!-- ========= -->
<Grid x:Name="root" Margin="10,10,10,10">
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="25" />
        <RowDefinition Height="25" />
        <RowDefinition Height="40" />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="40" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <!-- ========= -->
    <!-- Data Grid -->
    <!-- ========= -->
    <ListView x:Name="dataGrid" Grid.Row="0" Grid.ColumnSpan="2" ItemsSource="{Binding}">
        <ListView.View>
            <GridView>
                <!-- first solution -->
                <GridViewColumn x:Name="gridColumnName" Header="Name" Width="160">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <ContentControl Content="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <!-- second solution -->
                <GridViewColumn x:Name="gridColumnPath" Header="Path" DisplayMemberBinding="{Binding Path=Path}" Width="490" />
            </GridView>
        </ListView.View>
    </ListView>

    <!-- ========= -->
    <!-- Edit Menu -->
    <!-- ========= -->
    <Label Content="Name:" Grid.Row="1" Grid.Column="0" VerticalAlignment="Bottom" HorizontalAlignment="Left"/>
    <TextBox x:Name="txtBoxName" Grid.Row="1" Grid.Column="1" Width="250" VerticalAlignment="Bottom" HorizontalAlignment="Left" 
             DataContext="{Binding ElementName=dataGrid, Path=SelectedItem}" 
             Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

    <Label Content="Path:" Grid.Row="2" Grid.Column="0" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
    <TextBox x:Name="txtBoxPath" Grid.Row="2" Grid.Column="1" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" 
             DataContext="{Binding ElementName=dataGrid, Path=SelectedItem}" 
             Text="{Binding Path=Path, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

Object List class:

class ItemList : ObservableCollection<LdapItem>
{
    public ItemList()
        : base()
    { 
    }
}

Object class:

class LdapItem : INotifyPropertyChanged
{
    #region constructor

    public LdapItem(String name, String path)
    {
        this.iD = Guid.NewGuid().ToString();
        this.name = name;
        this.path = path;
    }

    #endregion

    #region public proterties

    public String ID
    {
        get { return iD; }
    }

    public String Name
    {
        get { return name; }
        set { name = value; }
    }

    public String Path
    {
        get { return path; }
        set { path = value; }
    }

    #endregion

    #region public methods

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

    #endregion

    #region private variables

    private String name = String.Empty;
    private String path = String.Empty;
    private String iD = String.Empty;

    #endregion

    public event PropertyChangedEventHandler PropertyChanged;
}

any ideas why updating the GridView doesnt work?

If you have a number of models use a base class that implements INPC. Then change your property changed event handler to:

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}

This will eliminate the need to specify the model property being changed. Reduces the number of misspelling errors or forgetting to put the name in. Still needs to call this.OnPropertyChanged() though which you are missing in several setters.

The ItemList class doesn't make sense. It could be replaced with:

public ObservableCollection<LdapItem> LdapItems 

it seems like you forgot to fire the OnPropertyChangedEvent when your property changes:

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

If you don't fire the PropertyChanged event, WPF will not be able to see if the object has changed.

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