2011-05-06 2 views
6

MVVM 응용 프로그램에서 작업 중입니다. & 광택을 내기 시작했습니다. & 광택 기능이 있습니다. 내 페이지 왼쪽에서 Silverlight MVVM - Button Enable & Visibility 속성

, 나는 이러한 값을 표시하고있다 :

DateActivated 
DateCompleted 
DateTrialClosed 
DateAccountingClosed 

DB를의 날짜가 있다면, 나는 TextBlock의를 표시하고있다. 그렇지 않은 경우 "작업 주문 활성화", "작업 주문 완료"등의 버튼을 사용자에게 표시하고 있습니다.

나는이 각각의 가시성을 바인딩합니다 (4 textblock, 4 버튼) 컨트롤 ViewModelWindows.Visibility 내 고유 한 속성을 제어합니다. 내 설정자 SelectedWorkOrder에서 SelectedWorkOrder.DateActivated 속성 (예 :)의 현재 값을 평가하고 그에 따라 가시성 속성을 설정합니다. 이것은 약간 장황하지만 예상대로 작동합니다.

내 다음 단계는 첫 번째 이후 눈에 보이는 버튼 (논리는 간단하다 .... 버튼 1을 클릭 할 때까지 버튼 2를 클릭 할 수 모두 1 & 2까지왔다 버튼 3을 클릭 할 수 없습니다 비활성화하는 것입니다 클릭). 이 방법을 구현하는 가장 좋은 방법은 무엇인지 모르겠습니다. 참고로이 프로젝트에서 이미 프로젝트에 boolToVisibility 값 변환기가 있습니다. 지금 구현하고있는 것과 다를 수 있습니다 (아래 VM 코드 참조).

<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 코드 :

현재 나는 내 XAML이이

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

(나는 새로운 DateTime 경우를 인스턴스화하고있어 같은 날짜 내 데이터베이스 액세스 레이어에서 1/1/0001로 설정 Is DBNull.Value = true)

+2

내가 강력하게 사용하는 것이 좋습니다 ['DateTime.MinValue'] (http://msdn.microsoft.com/en-us/library/system.datetime.minvalue.aspx) DateActivated를 문자열로 변환하고 "1/1/0001"과 비교하는 것보다 –

답변

2

오늘 저녁에도 비슷한 문제가 발생했습니다 .-)

이런 종류의 작업을 수행하는 가장 좋은 방법은 ViewModel의 속성에 대한 바인딩 가시성입니다.

이러한 각 변수에 대해 변환기를 사용할 수 있으므로 (예상 한대로 Visibility.Collapsed 또는 Visibility.Visible을 반환 할 수 있습니다.)).

이러한 각 단추에 대해 "CanExecute"메서드를 사용할 수 있으므로 button1을 누를 때까지 (예를 들어 부울 변수와 함께) 단추 2를 실행할 수 없습니다. 이 버튼을 사용하여 명령을 사용하면 각 버튼과 연관된 코드가 ModelView에 표시됩니다.

예를 들어 월요일에 내 작업에서 붙여 넣을 수 있습니다 :-).

여기에 직접 코딩하여 약간의 예가 있습니다 (저는 여기에 실버 라이트를 설치하지 않았습니다).

로보기는 다음과 같이해야한다 :

<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인지 기억할 수 없음)를 구현하고 있으므로 어렵지 않아야합니다. 나는 그 방법을 사용 해본 적이 없으므로, 방아쇠를 당기는 법을 모르겠습니다. 고마워. –

+0

몇 가지 예제를 찾으려면 조금씩 살펴 보겠습니다. 휴식 시간에 :-P – zapico

+0

감사합니다. 나는 명령을 사용하는 것에 익숙하다. 나는 이미 변환기를 가지고있다. 나는 코드를 재사용하는 것이 더 좋다는 것을 추상화하는 것을 볼 수는 있지만, 지금은 내 코드보다 덜 상세하다는 것을 확신하지 못한다. –

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 

가, 가시성 및 기타 데이터를 결합 특성 선언 :

는 명령입니다

공공 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> 
+0

그래서 지금까지 이걸 가지고 있습니다. 내가 모르는 것은 장애인/가능 자산에 대해해야 할 일입니다. –

+0

단추가있는 경우 canexecute 메서드로 인해 단추가 사용/사용되지 않도록 설정됩니다. OnCanExecuted 메서드가 변경 될 수 있다고 생각되면 (예 : 속성 집합에서) OnCanExecuted 메서드를 호출해야합니다. this.LoginCommand.OnCanExecuteChanged(); – zapico