Satya Praksh Mishra Ответов: 2

Опрация творога с использованием MVVM в WPF


невозможно получить значения текстового поля в viewmodel

[edit]добавлен блок кода-OriginalGriff [/edit]

Что я уже пробовал:

код пользовательского интерфейса-->


<Grid Margin="0,0,0,20">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListView Name="UserGrid" Grid.Row="1" Margin="4,242,12,-21"  ItemsSource="{Binding Users}" Grid.RowSpan="2"  >
            <ListView.View>
                <GridView x:Name="grdTest">
                    <GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"  Width="50"/>
                    <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}"  Width="80" />
                    <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
                    <GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
                    <GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
                    <GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
                </GridView>
            </ListView.View>
        </ListView>
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtUserId" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.UserId,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtFirstName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.FirstName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,62,0,0" Name="txtLastName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=UserGrid,Path=SelectedItem.LastName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <Label Content="UserId" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" />
        <Label Content="Last Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,60,0,0"  VerticalAlignment="Top" />
        <Label Content="First Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" VerticalAlignment="Top" />
        <Button Content="Update" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="184,199,0,0"  VerticalAlignment="Top" Width="95"
                Command="{Binding UpdateCommand,Source={StaticResource VM}}"  />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,87,0,0"  VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.City, ElementName=UserGrid,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <Label Content="Country" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,141,0,0"  VerticalAlignment="Top" />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,150,0,0"  VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.Country, ElementName=UserGrid,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <Label Content="City" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,86,0,0"  VerticalAlignment="Top" />
        <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,115,0,0" VerticalAlignment="Top" Width="178" Text="{Binding SelectedItem.State, ElementName=UserGrid,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        <Label Content="State" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,113,0,0"  VerticalAlignment="Top" />
        <Button Content="Save" HorizontalAlignment="Left" Margin="80,199,0,0" Grid.Row="1" VerticalAlignment="Top" Width="99"
                Command="{Binding SaveCommand,Source={StaticResource VM}}" />
        <Button Content="Delete" HorizontalAlignment="Left" Margin="297,199,0,0" Grid.Row="1" VerticalAlignment="Top" Width="80" Command="{Binding DeleteCommand,Source={StaticResource VM}}" />
        <Button Content="Canceal" Command="{Binding CancealComand,Source={StaticResource VM}}"
                HorizontalAlignment="Left" Margin="394,199,0,0" Grid.Row="1" VerticalAlignment="Top" Width="74"/>
    </Grid>


класс моделей:-
public class User : INotifyPropertyChanged
    {
        private int userId;
        private string firstName;
        private string lastName;
        private string city;
        private string state;
        private string country;

        public int UserId
        {
            get
            {
                return userId;
            }
            set
            {
                userId = value;
                OnPropertyChanged("UserId");
            }
        }
        public string FirstName
        {
            get
            {
                return firstName;
            }
            set
            {
                firstName = value;
                OnPropertyChanged("FirstName");
            }
        }
        public string LastName
        {
            get
            {
                return lastName;
            }
            set
            {
                lastName = value;
                OnPropertyChanged("LastName");
            }
        }
        public string City
        {
            get
            {
                return city;
            }
            set
            {
                city = value;
                OnPropertyChanged("City");
            }
        }
        public string State
        {
            get
            {
                return state;
            }
            set
            {
                state = value;
                OnPropertyChanged("State");
            }
        }
        public string Country
        {
            get
            {
                return country;
            }
            set
            {
                country = value;
                OnPropertyChanged("Country");
            }
        }


        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion
    }

ViewModel Class:-
 private ObservableCollection<user> _UsersList;
        public UserViewModel()
        {
            

            getUSerList();
        }
        public ObservableCollection<user> Users
        {
            get { return _UsersList; }
            set { _UsersList = value; }
        }
         #region SaveCommand
        private ICommand saveCommand;
        public ICommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                {
                    saveCommand = new RelayCommand(SaveExecuted, CanSaveExecute);
                }
                return saveCommand;
            }

        }

        public bool CanSaveExecute(object parameter)
        {
            // for save command 
            User _uuser=new User ();

            int str = _uuser.UserId;

            return true;
        }
        public void SaveExecuted(object parameter)
        {
            string str = userId;



            MessageBox.Show("Save Button clicked");
        }
        #endregion
  #region INotifyPropertyChanged

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

Graeme_Grant

Вы хотите сказать, что когда вы нажимаете на кнопки, ничего не происходит?

Foothill

Не могли бы вы изменить UpdateSourceTrigger=PropertyChanged в текстовом поле на UpdateSourceTrigger=SelectionChanged и посмотреть, что произойдет? Я предполагаю, что вы хотите отобразить дополнительную информацию об элементе, который пользователь выбирает в ListView.

2 Ответов

Рейтинг:
10

Graeme_Grant

В вашем коде есть несколько проблем в Xaml, которые вызвали проблемы. Это всегда хорошая идея, чтобы держать его как можно более чистым, чтобы сделать его читаемым. Итак, вот вам пересмотренная версия:

<Window x:Class="WpfListViewEdit.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:WpfListViewEdit"

        mc:Ignorable="d"

        Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen">

    <Window.DataContext>
        <local:UserViewModel/>
    </Window.DataContext>

    <Grid Margin="20">
        <Grid.Resources>
            <Style TargetType="Label">
                <Setter Property="HorizontalAlignment" Value="Right"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="Margin" Value="0 0 4 0"/>
            </Style>
            <Style TargetType="TextBox">
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                <Setter Property="VerticalAlignment" Value="Bottom"/>
                <Setter Property="Margin" Value="0 4"/>
            </Style>
            <Style TargetType="Button">
                <Setter Property="Margin" Value="10 0"/>
                <Setter Property="Padding" Value="10 5"/>
            </Style>
        </Grid.Resources>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="200" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>

        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <Label Content="_Id"

               Target="{Binding ElementName=txtUserId}" />
        <TextBox Name="txtUserId" Grid.Column="1" 

                 Text="{Binding ElementName=UserGrid, Path=SelectedItem.UserId, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

        <Label Content="_First Name" Grid.Row="1"

               Target="{Binding ElementName=txtFirstName}" />
        <TextBox Name="txtFirstName" Grid.Row="1" Grid.Column="1" 

                 Text="{Binding ElementName=UserGrid, Path=SelectedItem.FirstName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

        <Label Content="_Last Name" Grid.Row="2"

               Target="{Binding ElementName=txtLastName}" />
        <TextBox Name="txtLastName" Grid.Row="2" Grid.Column="1" 

                 Text="{Binding ElementName=UserGrid, Path=SelectedItem.LastName,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

        <Label Content="C_ity" Grid.Row="3"

               Target="{Binding ElementName=txtCity}" />
        <TextBox Name="txtCity" Grid.Row="3" Grid.Column="1" 

                 Text="{Binding ElementName=UserGrid, Path=SelectedItem.City, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

        <Label Content="S_tate" Grid.Row="4"

               Target="{Binding ElementName=txtState}"/>
        <TextBox Name="txtState" Grid.Row="4" Grid.Column="1"

                 Text="{Binding ElementName=UserGrid, Path=SelectedItem.State, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

        <Label Content="C_ountry" Grid.Row="5"

               Target="{Binding ElementName=txtCountry}" />
        <TextBox Name="txtCountry" Grid.Row="5" Grid.Column="1"

                 Text="{Binding ElementName=UserGrid, Path=SelectedItem.Country ,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

        <StackPanel Orientation="Horizontal" Grid.Row="6" Grid.ColumnSpan="3" Margin="0 10" HorizontalAlignment="Center">
            <Button Content="_Save"  Command="{Binding SaveCommand}" />
            <Button Content="_Update" Command="{Binding UpdateCommand}" />
            <Button Content="_Delete" Command="{Binding DeleteCommand}" />
            <Button Content="_Cancel" Command="{Binding CancelComand}"/>
        </StackPanel>

        <ListView Name="UserGrid" Grid.Row="7" ItemsSource="{Binding Users}" Grid.ColumnSpan="3"  >
            <ListView.View>
                <GridView x:Name="grdTest">
                    <GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId}" Width="50"/>
                    <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="80" />
                    <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
                    <GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
                    <GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
                    <GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
                </GridView>
            </ListView.View>
        </ListView>

    </Grid>

</Window>

При наличии этих изменений окно работает так, как и ожидалось, если будут предоставлены (фиктивные) данные. При выборе строк в listview текстовые поля отражают выбор; любые изменения, внесенные в текстовые поля, отражаются в ListView; все это происходит в режиме реального времени.

Макет кажется перевернутым. Я ожидал бы, что Listview будет находиться вверху, кнопки добавления, редактирования, удаления будут находиться рядом с ListView (сбоку или снизу), а панель редактирования (поля редактирования с кнопками Save &Cancel) появится (появится в поле зрения) отдельно внизу или всплывет в окне редактирования при использовании одной из кнопок ListView. Что-то вроде этого:
<Window x:Class="WpfListViewEdit.MainWindow"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

        xmlns:local="clr-namespace:WpfListViewEdit"

        mc:Ignorable="d"

        Title="MainWindow" Height="480" Width="600" WindowStartupLocation="CenterScreen">

    <Window.DataContext>
        <local:UserViewModel/>
    </Window.DataContext>

    <Grid Margin="20">
        <Grid.Resources>
            <Style TargetType="Label">
                <Setter Property="HorizontalAlignment" Value="Right"/>
                <Setter Property="VerticalAlignment" Value="Center"/>
                <Setter Property="Margin" Value="0 0 4 0"/>
            </Style>
            <Style TargetType="TextBox">
                <Setter Property="HorizontalAlignment" Value="Stretch"/>
                <Setter Property="VerticalAlignment" Value="Bottom"/>
                <Setter Property="Margin" Value="0 4"/>
            </Style>
            <Style TargetType="Button">
                <Setter Property="Margin" Value="10 0 0 0"/>
                <Setter Property="Padding" Value="10 5"/>
            </Style>
        </Grid.Resources>
        <Grid.RowDefinitions>
            <RowDefinition MinHeight="140"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <ListView Name="UserGrid" ItemsSource="{Binding Users}" Grid.ColumnSpan="3"  >
                <ListView.View>
                    <GridView x:Name="grdTest">
                        <GridViewColumn Header="UserId" DisplayMemberBinding="{Binding UserId}" Width="50"/>
                        <GridViewColumn Header="First Name" DisplayMemberBinding="{Binding FirstName}" Width="80" />
                        <GridViewColumn Header="Last Name" DisplayMemberBinding="{Binding LastName}" Width="100" />
                        <GridViewColumn Header="City" DisplayMemberBinding="{Binding City}" Width="80" />
                        <GridViewColumn Header="State" DisplayMemberBinding="{Binding State}" Width="80" />
                        <GridViewColumn Header="Country" DisplayMemberBinding="{Binding Country}" Width="100" />
                    </GridView>
                </ListView.View>
            </ListView>

            <StackPanel Orientation="Horizontal" Grid.Row="1" Margin="0 10"

                        HorizontalAlignment="Right">
                <Button Content="_Add"  Command="{Binding AddCommand}" />
                <Button Content="_Update" Command="{Binding UpdateCommand}" />
                <Button Content="_Delete" Command="{Binding DeleteCommand}" />
            </StackPanel>
        </Grid>

        <GroupBox Header="EDIT DETAILS" Grid.Row="1" Padding="10">

            <Grid Grid.Row="1">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <


Рейтинг:
1

Valerii Tereshchenko

{Binding ElementName=UserGrid, Path=SelectedItem.Идентификатор Пользователя,Режим=С Двусторонним Движением, UpdateSourceTrigger=PropertyChanged, Как}


элемент управления ListView.Элемент не является пользователем. Это экземпляр ListViewItem (или что-то в этом роде).
Вы должны использовать SelectedValue вместо SelectedItem.
Это также может быть хорошей идеей, чтобы добавить свойство SelectedUser к UserViewModel и
1) привязать SelectedValue ListView к этому свойству
2) свяжите свои текстовые поля, например {Binding SelectedUser.Идентификатор Пользователя,Режим=С Двусторонним Движением}
В этом случае вы не будете использовать ElementName в привязке. Привязка по имени элемента-не лучший выбор.