c# - 在 Viewmodel 中保存 View 的更改吗?

标签 c# wpf binding oneway

我正在尝试显示一个模型,并且想在用户单击按钮时保存它。 (将 ModelView OneWay 绑定(bind)到模型,如果按下保存按钮,我会手动更新源。) 这可能吗?

这里我创建了一个关于我的问题的小例子。 (不是 MVVM!)

MainWindow.xaml

<Grid>
        <Grid.DataContext>
            <ViewModel:MainViewModel/>
        </Grid.DataContext>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <local:PersonListView Grid.Column="0" DataContext="{Binding ViewModel_PersonList}"/>
        <local:PersonView Grid.Column="1" DataContext="{Binding ViewModel_Person}"/>
    </Grid>

PersonListView.xaml

<ListView ItemsSource="{Binding PersonList}" SelectedItem="{Binding SelectedPerson}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding LastName}"/>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

PersonView.xaml

<Grid DataContext="{Binding}">
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition/>
        <RowDefinition Height="auto"/>
    </Grid.RowDefinitions>
    <TextBlock Text="First Name:" Grid.Column="0" Grid.Row="0" Margin="5"/>
    <TextBlock Text="Last Name:" Grid.Column="0" Grid.Row="1" Margin="5"/>
    <TextBlock Text="Age:" Grid.Column="0" Grid.Row="2" Margin="5"/>
    <TextBox Text="{Binding Path=Person.FirstName, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="0" Margin="5"/>
    <TextBox Text="{Binding Path=Person.LastName, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="1" Margin="5"/>
    <TextBox Text="{Binding Path=Person.Age, UpdateSourceTrigger=Explicit}" Grid.Column="1" Grid.Row="2" Margin="5"/>
    <Button Content="Save" Command="{Binding SaveCommand}" Grid.Column="1" Grid.Row="4"/>
</Grid>

Person.cs

public class Person : INotifyPropertyChanged
    {
        private string firstName;
        public string FirstName
        {
            get { return firstName; }
            set
            {
                firstName = value;
                OnPropertyChanged("FirstName");
            }
        }

        private string lastName;
        public string LastName
        {
            get { return lastName; }
            set
            {
                lastName = value;
                OnPropertyChanged("LastName");
            }
        }

        private int age;
        public int Age
        {
            get { return age; }
            set
            {
                age = value;
                OnPropertyChanged("Age");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

MainViewModel.cs

public class MainViewModel : ViewModelBase
    {
        /// <summary>
        /// Initializes a new instance of the MainViewModel class.
        /// </summary>
        public MainViewModel()
        {
            ViewModel_PersonList.PersonList.Add(new Model.Person()
            {
                LastName = "Test",
                FirstName = "John",
                Age = 20
            });
            ViewModel_PersonList.PersonList.Add(new Model.Person()
            {
                LastName = "Example",
                FirstName = "Luke",
                Age = 25
            });
            ViewModel_PersonList.SelectedPerson = ViewModel_PersonList.PersonList[1];

            ViewModel_Person.Person = ViewModel_PersonList.SelectedPerson;
        }

        ViewModel.PersonViewModel _ViewModel_Person = new ViewModel.PersonViewModel();
        public ViewModel.PersonViewModel ViewModel_Person
        {
            get
            {
                return _ViewModel_Person;
            }
            set
            {
                _ViewModel_Person = value;
                RaisePropertyChanged("ViewModel_Person");
            }
        }

        ViewModel.PersonListViewModel _ViewModel_PersonList = new ViewModel.PersonListViewModel();
        public ViewModel.PersonListViewModel ViewModel_PersonList
        {
            get
            {
                return _ViewModel_PersonList;
            }
            set
            {
                _ViewModel_PersonList = value;
                RaisePropertyChanged("ViewModel_PersonList");
            }
        }
    }

PersonListViewModel.css

 public class PersonListViewModel : ViewModelBase
    {
        ObservableCollection<Model.Person> _PersonList = new ObservableCollection<Model.Person>();
        public ObservableCollection<Model.Person> PersonList
        {
            get
            {
                return _PersonList;
            }
            set
            {
                _PersonList = value;
                RaisePropertyChanged("PersonList");
            }
        }

        Model.Person _SelectedPerson = new Model.Person();
        public Model.Person SelectedPerson
        {
            get
            {
                return _SelectedPerson;
            }
            set
            {
                MessengerInstance.Send<Model.Person>(value);
                _SelectedPerson = value;
                RaisePropertyChanged("SelectedPerson");
            }
        }
    }

PersonViewModel.cs

public class PersonViewModel : ViewModelBase
    {
        public PersonViewModel()
        {
            MessengerInstance.Register<Model.Person>(this, per => Person = per);
        }

        Model.Person _Person = new Model.Person();
        public Model.Person Person
        {
            get
            {
                return _Person;
            }
            set
            {
                _Person = value;
                RaisePropertyChanged("Person");
            }
        }

        private RelayCommand<Model.Person> _SaveCommand;
        public ICommand SaveCommand
        {
            get
            {
                if (_SaveCommand == null)
                    _SaveCommand = new RelayCommand<Model.Person>(SaveCommand_Execute, SaveCommand_CanExecute);
                return _SaveCommand;
            }
        }

        private bool SaveCommand_CanExecute(Model.Person newPerson)
        {
            return true;
        }

        private void SaveCommand_Execute(Model.Person newPerson)
        {
// Do my saving!
        }
    }

谢谢!

最佳答案

您可以设置Mode=TwoWay 并使用UpdateSourceTrigger=Explicit。引用下面的代码。

 <StackPanel>
        <TextBox Name="tb_1" Text="HelloWorld!"/>
        <TextBox Name="tb_2" Text="{Binding Path=Text, ElementName=tb_1, Mode=TwoWay,UpdateSourceTrigger=Explicit}"/>
        <Button Content="Update Source" Click="Button_Click"/>
    </StackPanel>

关于c# - 在 Viewmodel 中保存 View 的更改吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29658417/

相关文章:

c# - 如何在 radtreeview 项目中显示多于一张图像(wpf - telerik)

c# - WPF 工具包饼图不显示

c# - 托管与非托管

c# - 在 HTTPS 安全页面上引用 jQuery CDN?

wpf - WPF-如何获取按钮的IsFocused或GotFocus/LostFocus来触发按钮模板中元素的动画的开/关

silverlight - XAML - 绑定(bind)到 DataContext 并使用转换器?

.net - 将命令分配给 EventSetter

javascript - 我怎样才能用 jQuery 实现这个交互模型呢?

c# - 如何判断一个方法是直接还是间接调用了一个属性?

c# - 将 UNIX 时间格式的 UTC 时间转换为可读的 DateTime 格式?