0

我有一个包含员工详细信息(全名、年龄、职位)的网格和一个保存按钮。我希望只有在按下保存按钮时才会保存员工。我如何在 MVVM 中实现它?

    <TextBlock
        Margin="3"
        Text="Full Name:"
        VerticalAlignment="Center"
        />
    <TextBox 
        Grid.Column="1"
        Margin="3"
        Text="{Binding FullName, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True}"
        />     
    <TextBlock
        Grid.Row="1"
        Margin="3"
        Text="Age:"
        VerticalAlignment="Center"
        />
    <TextBox 
        Grid.Column="1"
        Grid.Row="1"
        Margin="3"
        Text="{Binding Age, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True}"
        />
    <TextBlock
        Grid.Row="2"
        Margin="3"
        Text="Position:"
        VerticalAlignment="Center"
        />
    <TextBox 
        Grid.Column="1"
        Grid.Row="2"
        Margin="3"
        Text="{Binding Position, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True}"
        />


    <Button
        Grid.Row="4"
        Grid.ColumnSpan="2"
        Content="Save"
        Command="{Binding SaveCommand}"
        Width="80"
        Height="22"
        Margin="3"
        HorizontalAlignment="Right"
        VerticalAlignment="Bottom"
        />

我的 View 模型没有实现 Save 方法:我不确定我知道如何处理显式绑定......

public string FullName
        {
            get { return _emp.FullName; }
            set 
            { 
                _emp.FullName = value;
                OnPropertyChanged("FullName");
            }
        }

        public int Age
        {
            get { return _emp.Age; }
            set 
            { 
                _emp.Age = value;
                OnPropertyChanged("Age");
            }
        }

        public string Position
        {
            get { return _emp.Position; }
            set 
            { 
                _emp.Position = value;
                OnPropertyChanged("Position");
            }
        }


        public EmployeeViewModel(Employee emp)
        {
            _emp = emp;

            _employees = new ObservableCollection<EmployeeViewModel>();

            if (_emp.Employees != null)
            {
                foreach (Employee employee in _emp.Employees)
                    _employees.Add(new EmployeeViewModel(employee));
            }
        }

        public string[] ValidatedProperties =
        {
            "FullName",
            "Age",
            "Position"
        };

        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand ??
                    (_saveCommand = new RelayCommand(Save, CanSave));
            }
            set { _saveCommand = value; }
        }

        private bool CanSave()
        {
            foreach (string property in ValidatedProperties)
                if (!string.IsNullOrEmpty(GetValidationError(property)))
                    return false;

            return true;
        }

        private void Save()
        {
            throw new NotImplementedException();    
        }
4

1 回答 1

0

经过一番挖掘,我发现了一些不错的技术,使用命令参数+转换器。 http://www.shujaat.net/2011/01/updatesourcetrigger-explicit-for-mvvm.html

所以在我的情况下:

    <TextBlock
        Margin="3"
        Text="Full Name:"
        VerticalAlignment="Center"
        />
    <TextBox 
        x:Name="FullNameTextBox"
        Grid.Column="1"
        Margin="3"
        Text="{Binding FullName, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True}"
        />     
    <TextBlock
        Grid.Row="1"
        Margin="3"
        Text="Age:"
        VerticalAlignment="Center"
        />
    <TextBox 
        x:Name="AgeTextBox"
        Grid.Column="1"
        Grid.Row="1"
        Margin="3"
        Text="{Binding Age, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True}"
        />
    <TextBlock
        Grid.Row="2"
        Margin="3"
        Text="Position:"
        VerticalAlignment="Center"
        />
    <TextBox  
        x:Name="PositionTextBox"
        Grid.Column="1"
        Grid.Row="2"
        Margin="3"
        Text="{Binding Position, UpdateSourceTrigger=Explicit, ValidatesOnDataErrors=True}"
        />


    <Button
        Grid.Row="4"
        Grid.ColumnSpan="2"
        Content="Save"
        Command="{Binding SaveCommand}"
        Width="80"
        Height="22"
        Margin="3"
        HorizontalAlignment="Right"
        VerticalAlignment="Bottom"
        >
        <Button.CommandParameter>
            <MultiBinding Converter="{StaticResource EmployeeConverter}">
                <Binding ElementName="FullNameTextBox" Path="Text" />
                <Binding ElementName="AgeTextBox" Path="Text" />
                <Binding ElementName="PositionTextBox" Path="Text" />
            </MultiBinding>
        </Button.CommandParameter>
    </Button>
</Grid>

对视图模型的更改:

private RelayCommand<object> _saveCommand;


public RelayCommand<object> SaveCommand
{
    get
    {
        return _saveCommand ??
            (_saveCommand = new RelayCommand<object>(Save, CanSave));
    }
    set { _saveCommand = value; }
}

private bool CanSave(object value)
{
    foreach (string property in ValidatedProperties)
        if (!string.IsNullOrEmpty(GetValidationError(property)))
            return false;

    return true;
}

private void Save(object value)
{
    string[] parameters = ((string)value).Split(new char[] { ':' });
    FullName = parameters[0];
    Age = Convert.ToInt32(parameters[1]);
    Position = parameters[2];
}

和小转换器:

public class EmployeeConverter : IMultiValueConverter
{
    public object Convert(object [] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string fullName = (string)values[0];
        string age = (string)values[1];
        string position = (string)values[2];

        return string.Format("{0}:{1}:{2}", fullName, age, position);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}
于 2013-04-16T11:37:12.457 回答