所以我在MVVM应用程序&我开始把一些闪耀和放大抛光功能。
在我页面的左侧,我显示的是这些值:
DateActivated
DateCompleted
DateTrialClosed
DateAccountingClosed
如果DB中有日期,我会在文本块中显示它。如果没有,我正在向用户显示一个按钮,说“激活工作订单”,“完成工作订单”等...
我将这8个(4个文本块,4个按钮)控件中每个控件的可见性绑定到ViewModel
类型Windows.Visibility
中的唯一属性。在我的SelectedWorkOrder
的setter中,我评估SelectedWorkOrder.DateActivated
属性的当前值(例如)并相应地设置可见性属性。这对我来说有点冗长,但它按预期工作。
我的下一步是在第一个之后禁用任何可见按钮(逻辑很简单......在单击按钮1之前无法单击按钮2。在1和2之前都不能单击按钮3点击)。我不确定实现这个的最佳方法是什么。作为一个FYI,我在我的项目中已经有一个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}" />
VM代码:
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
)
答案 0 :(得分:2)
今晚我遇到了类似的问题: - )
我认为执行此类操作的最佳方法是将可见性绑定到ViewModel中的属性。
您可以为每个变量使用转换器(这样您就可以在需要时返回Visibility.Collapsed或Visibility.Visible; - ))。
您可以对每个按钮使用“CanExecute”方法,因此在按下button1之前无法执行按钮2(例如,使用布尔变量)。您需要使用命令,因此与每个按钮关联的代码将位于ModelView中。
如果您需要示例,我可以在星期一将其粘贴到我的工作中: - )。
直接在这里编码的一个小例子(我这里没有安装silverlight)。
您的观点应该是这样的:
<Button Content="Activate Work Order" Command="{Binding ActivateWorkOrderCommand}" />
您可以搜索如何在MVVM中使用命令的示例,这里有simple example。
对于转换器,如果您仍然喜欢隐藏和显示按钮,则应声明一个实现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}}" />
希望这对你有帮助; - )
答案 1 :(得分:1)
这里举了一个例子。
这是一个简单的示例,当您单击一个按钮并在单击另一个按钮时注销时登录。
这些是命令:
#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 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);
}
}
在这个例子中,我们需要在用户登录时隐藏按钮,并在用户不显示时显示,所以我制作了这个转换器:
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>