2010-12-21 94 views
0

我很喜歡MVVM Light框架,就像很多人所說的那樣,簡單但是功能強大。當命令是按鈕不被禁用

我想禁用一個按鈕,做同樣的事情在EventToCommand示例(工作好,但目標或3.5)。我添加了一個IsEnabled事件,正在解僱。

我的程序目標是4.0。

我的命令被禁用,但按鈕保持啓用狀態。

我也在我的程序中添加了一個事件,並未開火。

不知道我在想什麼。

我的XAML:

<Window x:Class="MyWPFApp.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4" 
    xmlns:vw="clr-namespace:MyWPFApp.Views" 

    Title="MainWindow" 
    Height="300" 
    Width="300" 
    SizeToContent="WidthAndHeight" 
    DataContext="{Binding Source={StaticResource Locator}, Path=v_MainWindow}"> 

<Window.Resources> 
    <!--<ResourceDictionary x:Key="ResDict"> 
     <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary Source="/Skins/MainSkin.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 
    </ResourceDictionary>--> 
    <ControlTemplate x:Key="ButtonTemplate" 
        TargetType="Button"> 
     <Grid x:Name="Root" 
       Opacity="0.8" 
       RenderTransformOrigin="0.5,0.5"> 
      <Grid.RenderTransform> 
       <TransformGroup> 
        <ScaleTransform /> 
        <SkewTransform /> 
        <RotateTransform /> 
        <TranslateTransform /> 
       </TransformGroup> 
      </Grid.RenderTransform> 

      <VisualStateManager.VisualStateGroups> 
       <VisualStateGroup x:Name="CommonStates"> 
        <VisualStateGroup.Transitions> 
         <VisualTransition From="MouseOver" 
              GeneratedDuration="00:00:00.2000000" 
              To="Normal" /> 
         <VisualTransition From="Normal" 
              GeneratedDuration="00:00:00.2000000" 
              To="MouseOver" /> 
        </VisualStateGroup.Transitions> 
        <VisualState x:Name="Normal" /> 
        <VisualState x:Name="MouseOver"> 
         <Storyboard> 
          <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                  Duration="00:00:00.0010000" 
                  Storyboard.TargetName="Root" 
                  Storyboard.TargetProperty="(UIElement.Opacity)"> 
           <SplineDoubleKeyFrame KeyTime="00:00:00" 
                 Value="1" /> 
          </DoubleAnimationUsingKeyFrames> 
         </Storyboard> 
        </VisualState> 
        <VisualState x:Name="Pressed"> 
         <Storyboard> 
          <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                  Duration="00:00:00.0010000" 
                  Storyboard.TargetName="Root" 
                  Storyboard.TargetProperty="(UIElement.Opacity)"> 
           <SplineDoubleKeyFrame KeyTime="00:00:00" 
                 Value="1" /> 
          </DoubleAnimationUsingKeyFrames> 
          <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                  Duration="00:00:00.0010000" 
                  Storyboard.TargetName="Root" 
                  Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"> 
           <SplineDoubleKeyFrame KeyTime="00:00:00" 
                 Value="0.9" /> 
          </DoubleAnimationUsingKeyFrames> 
          <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                  Duration="00:00:00.0010000" 
                  Storyboard.TargetName="Root" 
                  Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"> 
           <SplineDoubleKeyFrame KeyTime="00:00:00" 
                 Value="0.9" /> 
          </DoubleAnimationUsingKeyFrames> 
         </Storyboard> 
        </VisualState> 
        <VisualState x:Name="Disabled"> 
         <Storyboard> 
          <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" 
                  Duration="00:00:00.0010000" 
                  Storyboard.TargetName="Root" 
                  Storyboard.TargetProperty="(UIElement.Opacity)"> 
           <SplineDoubleKeyFrame KeyTime="00:00:00" 
                 Value="0.4" /> 
          </DoubleAnimationUsingKeyFrames> 
         </Storyboard> 
        </VisualState> 
       </VisualStateGroup> 
      </VisualStateManager.VisualStateGroups> 
      <Rectangle Fill="{TemplateBinding Background}" 
         Stroke="Black" 
         RadiusX="8" 
         RadiusY="8" /> 
      <TextBlock HorizontalAlignment="Center" 
         VerticalAlignment="Center" 
         Text="{TemplateBinding Content}" 
         TextWrapping="Wrap" 
         FontSize="12" 
         FontWeight="Bold" /> 
     </Grid> 
    </ControlTemplate> 

    <Style x:Key="ButtonStyle" 
      TargetType="Button"> 
     <Setter Property="Template" 
       Value="{StaticResource ButtonTemplate}" /> 
     <Setter Property="Cursor" 
       Value="Hand" /> 
    </Style> 

</Window.Resources> 

<Grid x:Name="LayoutRoot"> 
    <Grid.RowDefinitions> 
     <RowDefinition /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="Auto" /> 
     <ColumnDefinition /> 
    </Grid.ColumnDefinitions> 
    <StackPanel Grid.Row="0" Grid.Column="0" Orientation="Vertical" HorizontalAlignment="Left"> 
     <Button Content="Change to Error Status" Style="{StaticResource ButtonStyle}" IsEnabledChanged="EnableChanged"> 
      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="Click"> 
        <cmd:EventToCommand Command="{Binding StatusCommand}" 
            CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Content}" MustToggleIsEnabled="True"/> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
     </Button> 
     <Button Content="Change to Warning" Style="{StaticResource ButtonStyle}" IsEnabledChanged="EnableChanged">    
      <i:Interaction.Triggers> 
       <i:EventTrigger EventName="Click"> 
        <cmd:EventToCommand Command="{Binding StatusCommand}" 
             CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Content}" MustToggleIsEnabled="True"/> 
       </i:EventTrigger> 
      </i:Interaction.Triggers> 
     </Button> 
     <Button Content="Success" IsEnabled="False"/> 
     <Button Content="Info"/> 
    </StackPanel> 
    <TextBlock Grid.Row="0" Grid.Column="1" 
       FontSize="36" 
       FontWeight="Bold" 
       Foreground="Purple" 
       Text="{Binding Welcome}" 
       VerticalAlignment="Center" 
       HorizontalAlignment="Center" 
       TextWrapping="Wrap"> 
     <!--<i:Interaction.Triggers> 
      <i:EventTrigger EventName="MouseEnter"> 
       <cmd:EventToCommand Command="{Binding StatusCommand}" 
            CommandParameter="Error" /> 
      </i:EventTrigger> 
     </i:Interaction.Triggers>--> 
    </TextBlock> 
    <vw:v_StatusBar Grid.Row="1" Grid.ColumnSpan="2" /> 

</Grid> 

我的代碼在視圖模型

using System.Windows; 
using GalaSoft.MvvmLight; 
using GalaSoft.MvvmLight.Command; 
using GalaSoft.MvvmLight.Messaging; 



namespace MyWPFApp.ViewModel 
{ 
/// <summary> 
/// This class contains properties that the main View can data bind to. 
/// <para> 
/// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel. 
/// </para> 
/// <para> 
/// You can also use Blend to data bind with the tool's support. 
/// </para> 
/// <para> 
/// See http://www.galasoft.ch/mvvm/getstarted 
/// </para> 
/// </summary> 
public class vm_MainWindow : ViewModelBase 
{ 
    public string Welcome 
    { 
     get 
     { 
      return "Welcome to Geert's WPF template (based on MVVM Light)"; 
     } 
    } 

    private string _status = "Initialized..."; 

    public string Status 
    { 
     get 
     { 
      return _status; 
     } 

     private set 
     { 
      if (_status == value) 
      { 
       MessageBox.Show("Status is already " + value); 
       return; 
      } 

      _status = value; 

      MessageBox.Show("Setting status to " + _status); 
      Messenger.Default.Send<string>(value, "StatusChange"); 

     } 
    } 

    public RelayCommand<string> StatusCommand 
    { 
     get; 
     private set; 
    } 


    /// <summary> 
    /// Initializes a new instance of the MainViewModel class. 
    /// </summary> 
    public vm_MainWindow() 
    { 
     if (IsInDesignMode) 
     { 
      // Code runs in Blend --> create design time data. 
     } 
     else 
     { 
      // Code runs "for real" 

      StatusCommand = new RelayCommand<string>(p => Status = string.Format("{0}", p), p => p != _status); 

     } 
    } 

    ////public override void Cleanup() 
    ////{ 
    //// // Clean up if needed 

    //// base.Cleanup(); 
    ////} 
} 

}

回答

0

發現問題,CanExecuteChanged簡單從來沒有發射!!!!!!

第一,我加了(在relaycommand)什麼建議在這裏的話: http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(SYSTEM.WINDOWS.INPUT.COMMANDMANAGER.REQUERYSUGGESTED);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true

然後我注意到,只有最後一個按鈕被啓用/禁用。

再次合乎邏輯,在relaycommand中添加的每個處理程序都覆蓋了前一個處理程序。

所以,我在eventtocommand中添加了事件處理支持。

和,一切都很好。

會將我的更正寄給Buignon先生,希望他能正式覈對和發佈。

ps只針對WPF 4.0進行檢查和更改(僅我現在需要的)