Silverlight MVVM - Button Enable & Visibility properties
本文关键字:amp Visibility properties Enable MVVM Button Silverlight | 更新日期: 2023-09-27 17:55:26
所以我在MVVM应用程序工作,我开始在功能上加一些光彩和润色。
在我的页面左侧,我显示以下值:
DateActivated
DateCompleted
DateTrialClosed
DateAccountingClosed
如果数据库中有日期,我会在文本块中显示它。如果没有,我将向用户显示一个按钮,说"激活工作订单"、"完成工作订单"等......
我将这 8 个(4 个文本块,4 个按钮)控件中的每一个的可见性绑定到我的 Windows.Visibility
型ViewModel
中的唯一属性。在我的SelectedWorkOrder
中,我评估SelectedWorkOrder.DateActivated
属性的当前值(例如)并相应地设置可见性属性。这对我来说有点冗长,但它按预期工作。
我的下一步是在第一个按钮之后禁用任何可见按钮(逻辑很简单......在单击按钮 1 之前,无法单击按钮 2。在同时单击按钮 1 和 2 之前,无法单击按钮 3)。我不确定实现这一点的最佳方法是什么。仅供参考,我的项目中已经有一个 boolToVisibility 值转换器......我只是不确定实现它与我现在所做的有什么不同(请参阅下面的 VM 代码)。
目前,我的 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}" />
虚拟机代码:
if (_SelectedWorkOrder.DateActivated.ToShortDateString() != "1/1/0001")
{
ActivatedTextBlockVisibility = Visibility.Visible;
ActivatedButtonVisibility = Visibility.Collapsed;
}
else
{
ActivatedTextBlockVisibility = Visibility.Collapsed;
ActivatedButtonVisibility = Visibility.Visible;
}
(日期设置为1/1/0001
在我的数据库访问层中,因为我正在实例化一个新DateTime
,如果Is DBNull.Value = true
)
今晚我遇到了类似的问题:-)
我认为做这种事情的最好方法是将可见性绑定到 ViewModel 中的属性。
您可以对这些变量中的每一个使用转换器(因此您可以在预期时返回 Visibility.Collapsed 或 Visibility.Visible ;-))。
您可以对每个按钮使用"CanExecute"方法,以便在按下按钮 1 之前无法执行按钮 2(例如使用布尔变量)。您需要为此使用命令,以便与每个按钮关联的代码将位于模型视图中。
如果您需要示例,我可以在周一从我的工作中粘贴它们:-)。
直接在这里编码的小例子(我这里没有安装 silverlight)。
您的视图应该是这样的:
<Button Content="Activate Work Order" Command="{Binding ActivateWorkOrderCommand}" />
您可以搜索如何在 MVVM 中使用命令的示例,这里有一个简单的示例。
对于转换器,如果您仍然喜欢隐藏和显示按钮,则应声明一个实现 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;
}
因此,您的视图也应该链接转换器:
<Button Content="Activate Work Order" Visibility="{Binding DateActivated, Converter={StaticResource DateConverter}}" />
希望这对你有帮助;-)
这里有一个小例子。
这是一个简单的示例,当您单击一个按钮时登录,当您单击另一个按钮时注销。
这些是命令:
#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
若要绑定可见性和其他数据,请声明一个属性:
public const 字符串 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);
}
}
在这个例子中,我们需要在用户登录时隐藏按钮,并在用户未登录时显示它,所以我做了这个转换器:
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;
}
}
最后,我们必须将其绑定到视图上,注意转换器:
<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>