Silverlight MVVM - Power and Visibility Button Properties

So, I am working in an MVVM application, and I started using some of the gloss and polish features.

The following values ​​are displayed on the left side of my page:

DateActivated DateCompleted DateTrialClosed DateAccountingClosed 

If the database has a date, I display it in a text block. If not, I show the button to the user, saying “Activate work order”, “Full work order”, etc.

I bind the visibility of each of these 8 (4 text blocks, 4 buttons) controls to a unique property in the ViewModel of the Windows.Visibility type. In my SelectedWorkOrder installer, I compute the current value of the SelectedWorkOrder.DateActivated property (for example) and set the visibility properties accordingly. This is a bit detailed for me, but it works as expected.

My next step is to disable any visible buttons after the first (the logic is simple ... cannot press button 2 until button 1 is pressed. You cannot press button 3 until buttons 1 and 2 are pressed). I am not sure what the best way to implement this. Like FYI on this, I have a boolToVisibility value converter already in my project ... I'm just not sure that its implementation will be different from what I'm doing now (see VM code below).

I currently have this for my XAML:

 <TextBlock Text="Proposed:" /> <TextBlock Text="Activated:" /> <TextBlock Text="Eng Completed:" /> <TextBlock Text="Trial Close:" /> <TextBlock Text="Accounting Close:" /> <TextBlock Text="{Binding SelectedWorkOrder.EstimatedStartDate}" Visibility="{Binding ProposedVisibility}" /> <TextBlock Text="{Binding SelectedWorkOrder.DateActivated}" Visibility="{Binding ActivatedTextBlockVisibility}" /> <Button Content="Activate Work Order" Visibility="{Binding ActivatedButtonVisibility}" /> <TextBlock Text="{Binding SelectedWorkOrder.DateCompleted}" Visibility="{Binding EngineeringCompletedTextBlockVisibility}" /> <Button Content="Work Order Eng Complete" Visibility="{Binding EngineeringCompletedButtonVisibility}" /> <TextBlock Text="{Binding SelectedWorkOrder.DateClosed}" Visibility="{Binding TrialCloseTextBlockVisibility}" /> <Button Content="Close Work Order (Trial)" Visibility="{Binding TrialCloseButtonVisibility}" /> <TextBlock Text="{Binding SelectedWorkOrder.DateClosed}" Visibility="{Binding AccountingCloseTextBlockVisibility}" /> <Button Content="Close Work Order (Actual)" Visibility="{Binding AccountingCloseButtonVisibility}" /> 

VM Code:

 if (_SelectedWorkOrder.DateActivated.ToShortDateString() != "1/1/0001") { ActivatedTextBlockVisibility = Visibility.Visible; ActivatedButtonVisibility = Visibility.Collapsed; } else { ActivatedTextBlockVisibility = Visibility.Collapsed; ActivatedButtonVisibility = Visibility.Visible; } 

(The date is set to 1/1/0001 at my database access level, as I am creating a new DateTime if Is DBNull.Value = true )

+6
source share
2 answers

I had a similar problem tonight :-)

I think the best way to do this stuff is to bind visibility to a property in the ViewModel.

You can use a converter for each of these variables (so you can return Visibility.Collapsed or Visibility.Visible when expected ;-)).

You can use the “CanExecute” method for each of these buttons so that button 2 cannot be executed before button 1 is pressed (for example, using a boolean variable). You can use the commands to do this, so that the code associated with each button is in the ModelView.

If you need examples, I can insert them from my work on Monday :-).

A small example, directly coding it here (I don't have Silverlight installed here).

Your opinion should look like this:

 <Button Content="Activate Work Order" Command="{Binding ActivateWorkOrderCommand}" /> 

You can find examples of using commands in MVVM, here you have a simple example .

For converters, if you still prefer to hide and show buttons, you must declare a new class that implements IValueConverter:

 public class UniversalConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if(_SelectedWorkOrder.DateActivated.ToShortDateString() != "1/1/0001") { return Visibility.Collapsed; } else { return Visibility.Visible; } 

Thus, your view should also bind the converter:

 <Button Content="Activate Work Order" Visibility="{Binding DateActivated, Converter={StaticResource DateConverter}}" /> 

Hope this helps you; -)

+2
source

Here is a small example.

This is a simple example for logging in when you press one button and logging out when you click another.

These are the commands:

  #region Login Command public ViewModelCommand LoginCommand { get; set; } public void Login(object parameter) { Code.Session.Session.Sesion.Logged = true; } public bool CanLogin(object parameter) { return !Code.Session.Session.Sesion.Logged; } #endregion #region Logout Command public ViewModelCommand LogoutCommand { get; set; } public void Logout(object parameter) { Code.Session.Session.Sesion.Logged = false; } public bool CanLogout(object parameter) { return Code.Session.Session.Sesion.Logged; } #endregion 

To bind visibility and other data, declare a property:

public const string SesionPropertyName = "Sesion";

 private Model.Sesion _Sesion = Code.Session.Session.Sesion; public Model.Sesion Sesion { get { return _Sesion; } set { if (_Sesion == value) { return; } var oldValue = _Sesion; _Sesion = value; // Update bindings, no broadcast RaisePropertyChanged(SesionPropertyName); } } 

In this example, we need to hide the button during user registration and show it when the user did not, so I made this converter:

 public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if ((bool)value) { return Visibility.Collapsed; } else { return Visibility.Visible; } } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if ((Visibility)value == Visibility.Visible) { return false; } else { return true; } } 

Finally, we must bind it to the view, pay attention to the converter:

 <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="221*" /> <ColumnDefinition Width="140*" /> </Grid.ColumnDefinitions> <Button Content="Logout" Grid.Column="1" HorizontalAlignment="Stretch" Margin="2" Name="bLogout" VerticalAlignment="Stretch" Command="{Binding LogoutCommand}" /> <TextBlock Height="Auto" HorizontalAlignment="Stretch" Margin="2" Name="txtBlockUser" Text="{Binding Sesion.UserName}" VerticalAlignment="Center" TextWrapping="NoWrap" TextAlignment="Center" /> <Grid Grid.ColumnSpan="2" > <Button Content="Login" Command="{Binding LoginCommand}" Visibility="{Binding Sesion.Logged, Converter={StaticResource InverseBooleanVisibilityConverter}}"></Button> </Grid> </Grid> 
+1
source

Source: https://habr.com/ru/post/887480/


All Articles