我是 MVVM 的新手。我的視圖中有三個文本框和一個按鈕。我希望在填充所有這三個文本框時啟用該按鈕。我的看法如下:
<StackPanel Margin="1,1,1,1" Grid.Row="0">
<!--<Label Margin="2,2,2,2" Content="ID:"/>
<dxe:TextEdit Margin="2,2,2,2" Text="{Binding ElementName=StudentGrid, Path=SelectedItem.Id}"/>-->
<Label Margin="2,2,2,2" Content="Name:"/>
<dxe:TextEdit Margin="2,2,2,2" x:Name="Name" Text="{Binding Path=Name}" />
<Label Margin="2,2,2,2" Content="Last Name:"/>
<dxe:TextEdit Margin="2,2,2,2" x:Name="LastName" Text="{Binding Path=LastName}" />
<Label Margin="2,2,2,2" Content="Age:"/>
<dxe:TextEdit Margin="2,2,2,2" x:Name="Age" Text="{Binding Path=Age}" />
</StackPanel>
<ListView Name="StudentGrid" Grid.Row="1" Margin="1,1,1,1" ItemsSource="{Binding studentList}">
<ListView.View>
<GridView>
<GridViewColumn Header="ID" Width="50" DisplayMemberBinding="{DXBinding Id}"/>
<GridViewColumn Header="Name" Width="80" DisplayMemberBinding="{DXBinding Name}"/>
<GridViewColumn Header="Last Name" Width="80" DisplayMemberBinding="{DXBinding LastName}"/>
<GridViewColumn Header="Age" Width="50" DisplayMemberBinding="{DXBinding Age}"/>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Row="2" Margin="1,2,1,1">
<dx:SimpleButton x:Name="applybtn" Content="Insert" Width="60" HorizontalAlignment="Left" Margin="5,0,0,0" Command="{Binding Path=_myCommand}"/>
</StackPanel>
InserCommand代碼是:
public class InsertCommand : ICommand
{
public StudentListViewModel _viewModel { get; set; }
public InsertCommand(StudentListViewModel viewModel)
{
_viewModel = viewModel;
}
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
_viewModel.InsertStudent();
}
}
StudentListViewModel代碼是:
public class StudentListViewModel : INotifyPropertyChanged
{
private string _name;
private string _lastName;
private int _age;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public string LastName
{ get => _lastName;
set
{
_lastName = value;
OnPropertyChanged("LastName");
}
}
public int Age
{ get => _age;
set
{
_age = value;
OnPropertyChanged("Age");
}
}
public InsertCommand _myCommand { get; set; }
private ObservableCollection<Student> _studentList;
public StudentListViewModel()
{
_myCommand = new InsertCommand(this);
using (MyContext context = new MyContext())
{
_studentList = new ObservableCollection<Student>(context.Students.ToList());
};
}
public void InsertStudent()
{
Student st = new Student()
{
Name = _name,
LastName = _lastName,
Age = _age
};
using (var context = new MyContext())
{
context.Add(st);
context.SaveChanges();
_studentList.Add(st); //For Getting instatnt UI update
}
}
public ObservableCollection<Student> studentList
{
get
{
return _studentList;
}
set
{
_studentList = value;
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
uj5u.com熱心網友回復:
通常我創建系結驗證,以便我可以在其他文本框上重用。
然后在按鈕上,我創建觸發器以根據定義的驗證啟用或禁用按鈕。
<Button Comman="{Binding InsertCommand}" Content="Insert">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="False" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Name, Path=(Validation.HasError)}" Value="False"/>
<Condition Binding="{Binding ElementName=LastName, Path=(Validation.HasError)}" Value="False"/>
<Condition Binding="{Binding ElementName=Age, Path=(Validation.HasError)}" Value="False"/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="True" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
對于非常簡單的非空驗證,我沒有創建驗證,而是針對文本框的文本屬性進行測驗
<Button Comman="{Binding InsertCommand}" Content="Insert">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="IsEnabled" Value="True" />
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=Name, Path=Text}" Value=""/>
<Condition Binding="{Binding ElementName=LastName, Path=Text}" Value=""/>
<Condition Binding="{Binding ElementName=Age, Path=Text}" Value=""/>
</MultiDataTrigger.Conditions>
<Setter Property="IsEnabled" Value="False" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
uj5u.com熱心網友回復:
當所有這三個文本框都被填充時啟用按鈕。
創建一個bool名為 的新屬性IsButtonEnabled。
每當文本更改(雙向系結和更新系結中的源觸發器?->如何系結,我的答案)時,將當前字串實時推送到 VM 的屬性。
那些有問題的屬性,它們的值將在IsButtonEnabledgetter 中檢查。然后在每個字串的設定器中,添加一個OnPropertyChangedfor IsButtonEnabled。還系結IsButtonEnabled到正確的按鈕屬性以實作您想要的效果。
例子
// Doesn't need its own OnPropertyChanged, because that is set
// for every keystroke.
public bool IsButtonEnabled { get { return !string.IsNullOrEmpty(Name) &&
!string.IsNullOrEmpty(LastName) &&
!string.IsNullOrEmpty(Age); }}
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged("Name");
OnPropertyChanged("IsButtonEnabled");
InsertCommand.RaiseCanExecuteChanged();
}
}
public string LastName
...
set
{
_lastName = value;
OnPropertyChanged("LastName");
OnPropertyChanged("IsButtonEnabled");
...
public string Age
...
set
{
_age= value;
OnPropertyChanged("Age");
OnPropertyChanged("IsButtonEnabled");
....
Xaml
<dx:SimpleButton x:Name="applybtn" IsEnabled="{Binding IsButtonEnabled}" ...
給出了類似的答案
- DataTemplate.DataTrigger 檢查大于還是小于?
- WPF 多系結/聚合系結到集合
uj5u.com熱心網友回復:
為每個命令創建一個新類并不常見。
相反,使用 action / func 引數創建一個通用命令類來指定每個命令的邏輯。
public class RelayCommand : ICommand
{
private readonly Action _execute;
private readonly Func<bool> _canExecute;
public RelayCommand(Action execute) : this(execute, () => true)
{
}
public RelayCommand(Action execute, Func<bool> canExecute)
{
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
_canExecute = canExecute;
}
public bool CanExecute(object parameter) => _canExecute.Invoke();
public void Execute(object parameter) => _execute.Invoke();
public event EventHandler CanExecuteChanged;
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}
然后,在您可以將按鈕系結到的 ViewModel 中創建此類的實體。
public class StudentListViewModel : INotifyPropertyChanged
{
private string _name;
private string _lastName;
private int _age;
public string Name
{
get => _name;
set
{
_name = value;
OnPropertyChanged("Name");
InsertCommand.RaiseCanExecuteChanged();
}
}
public string LastName
{ get => _lastName;
set
{
_lastName = value;
OnPropertyChanged("LastName");
InsertCommand.RaiseCanExecuteChanged();
}
}
public int Age
{ get => _age;
set
{
_age = value;
OnPropertyChanged("Age");
InsertCommand.RaiseCanExecuteChanged();
}
}
public RelayCommand InsertCommand { get; }
public StudentListViewModel()
{
InsertCommand = new RelayCommand(() => InsertStudent(),
() => !string.IsNullOrEmpty(Name) && !string.IsNullOrEmpty(LastName) && Age > 0);
...
}
public void InsertStudent()
{
....
}
}
要獲得一種更簡潔的方式來處理命令重繪 ,以便每個屬性都不需要關心它的使用方式,請查看我的博客文章。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/444518.html
