2011-05-06 61 views
6

因此,我正在MVVM應用程序中工作&我開始在功能上放一些亮點&波蘭語。Silverlight MVVM - 按鈕啓用和可見性屬性

在我的頁面的左邊,我顯示這些值:

DateActivated 
DateCompleted 
DateTrialClosed 
DateAccountingClosed 

如果有一個數據庫中的日期,我的文字塊顯示它。如果沒有,我會向用戶顯示一個按鈕,說「激活工作訂單」,「完成工作訂單」等...

我綁定這8(4文本塊, 4按鈕)控制到類型Windows.VisibilityViewModel中的一個獨特屬性。在我的設置器SelectedWorkOrder中,我評估SelectedWorkOrder.DateActivated屬性的當前值(例如)並相應地設置可見性屬性。這對我來說略顯冗長,但它按預期工作。

我的下一步是在第一個按鈕之後禁用任何可見的按鈕(邏輯很簡單...不能點擊按鈕2直到按鈕1被點擊,不能點擊按鈕3直到兩個& 2已經點擊)。我不確定實現這一點的最佳方式是什麼。作爲一個參考,我有一個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

+2

我強烈建議使用['DateTime.MinValue'(http://msdn.microsoft.com/en-us/library/system.datetime.minvalue.aspx)而不是將DateActivated轉換爲字符串並將其與「1/1/0001」進行比較。 – 2011-05-06 21:48:47

回答

2

我今天晚上有類似的問題:-)

我認爲做這種東西的最好方法是將可見性綁定到ViewModel中的一個屬性。

您可以爲每個變量使用一個轉換器(因此您可以在預期時返回Visibility.Collapsed或Visibility.Visible ;-))。

對於每個按鈕,您都可以使用「CanExecute」方法,這樣按鈕2無法執行,直到按下按鈕1(例如,使用布爾變量)。您需要爲此使用命令,因此與每個按鈕關聯的代碼將位於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}}" /> 

希望這有助於你;-)

+0

是的例子會很好。我ViewModelBase已經在實施的ICommand與inotify的(不記得哪個接口擁有CanExecute),這樣應該不難。我只是不確定如何觸發它,因爲我從來沒有使用過這種方法。謝了哥們。 – 2011-05-06 20:46:05

+0

我會尋找一點點地找到一些例子,我在休息時間:-P – zapico 2011-05-06 20:53:42

+0

謝謝,我會看一看。我非常熟悉使用命令,而且我已經有了一個轉換器。我只是不確定它現在的代碼是否比我的代碼冗長,儘管我可以看到將它抽象爲它自己的類更適合代碼重用。 – 2011-05-08 03:46:24

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 

要綁定的可見性和其它數據,聲明一個屬性:

公共常量字符串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> 
+0

所以我已經得到了這一點 - 我不知道的是我應該做的關於殘疾人/啓用財產。 – 2011-05-09 18:11:00

+0

如果您有按鈕,它們將由於未執行方法而被啓用/禁用。你必須調用OnCanExecuted方法,當你認爲它可以更改(例如,在屬性中設置):this.LoginCommand.OnCanExecuteChanged(); – zapico 2011-05-10 08:37:32