我有一個WPF應用程序,它不會讓我點擊按鈕,直到有點時間過去,但是這種行爲是隨機的,只發生在某些時間。大部分時間窗口呈現,我可以立即點擊說按鈕。當窗口呈現時,按鈕不可點擊
主窗口:
<views:StatusBox DockPanel.Dock="Left" Visibility="{Binding Editing, Converter={StaticResource BoolToVisibleConverter}}" />
</DockPanel>
用戶控制:
<StackPanel Orientation="Horizontal">
<!--Read Button-->
<Button Content="Read " x:Name="ReadBtn" Command="{Binding ReadCMD}" Padding="10,5" Margin= "10,0" IsEnabled="{Binding ReadEnabled}" />
<!--Save Button-->
<Button Content="Save " x:Name="SaveBtn" Command="{Binding SaveCMD}" Padding="10,5" Margin= "10,0" IsEnabled="{Binding SaveEnabled}"
Background="{StaticResource {x:Static SystemColors.ControlLightBrushKey}}">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<DataTrigger Binding="{Binding IsSaveNeeded}" Value="Yes">
<DataTrigger.EnterActions>
<BeginStoryboard x:Name="FlashBackground">
<Storyboard BeginTime="00:00:00" RepeatBehavior="Forever" >
<ColorAnimation Storyboard.TargetProperty="Background.Color" Duration="00:00:00.25" AutoReverse="True" To="Red" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<StopStoryboard BeginStoryboardName="FlashBackground" />
</DataTrigger.ExitActions>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<!--Load Button-->
<Button Content="Load " x:Name="LoadBtn" Command="{Binding LoadCMD}" Padding="10,5" Margin= "10,0" IsEnabled="{Binding LoadEnabled}" />
<!--Print Button-->
<Button Content="Print" x:Name="PrintBtn" Command="{Binding PrintCMD}" Padding="10,5" Margin= "10,0" IsEnabled="{Binding PrintEnabled}" />
<!--Exit Button-->
<Button Content="Exit" x:Name="ExitBtn" Command="{Binding ExitCMD}" Padding="10,5" Margin= "10,0" />
</StackPanel>
視圖模型
private bool _tab1_Selected;
public bool tab1_Selected
{
get
{
return _tab1_Selected;
}
set
{
_tab1_Selected = value;
if (value)
{
CommMode = (byte)PacketType.tab1_DUMP;
if (tab1needsSaving)
{
IsSaveNeeded = SaveNeeded.Yes;
}
else
{
IsSaveNeeded = SaveNeeded.No;
}
}
NotifyPropertyChanged("tab1_Selected");
NotifyPropertyChanged("SaveEnabled");
NotifyPropertyChanged("ProgramEnabled");
NotifyPropertyChanged("Editing");
}
}
private bool _tab2_Selected;
public bool tab2_Selected
{
get
{
return _tab2_Selected;
}
set
{
_tab2_Selected = value;
if (value)
{
CommMode = (byte)PacketType.tab2_DUMP;
if (tab2needsSaving)
{
IsSaveNeeded = SaveNeeded.Yes;
}
else
{
IsSaveNeeded = SaveNeeded.No;
}
}
NotifyPropertyChanged("tab2_Selected");
NotifyPropertyChanged("SaveEnabled");
NotifyPropertyChanged("ProgramEnabled");
NotifyPropertyChanged("Editing");
}
}
public bool Editing
{
get
{
return tab2_Selected || tab1_Selected;
}
}
private bool _saveEnabled;
public bool SaveEnabled
{
get
{
//return _saveEnabled;
return ((tab1_Selected && tab1Data != null && tab1Data.Count > 0) || (tab2_Selected && tab2Data != null && tab2Data.Count > 0) && _saveEnabled);
}
set
{
_saveEnabled = value;
NotifyPropertyChanged("SaveEnabled");
}
}
private bool _programEnabled;
public bool ProgramEnabled
{
get
{
//return _saveEnabled;
return ((tab1_Selected && tab1Data != null && tab1Data.Count > 0) || (tab2_Selected && tab2Data != null && tab2Data.Count > 0) && _programEnabled);
}
set
{
_programEnabled = value;
NotifyPropertyChanged("ProgramEnabled");
}
}
命令:
public ICommand ReadCMD { get; set; }
public ICommand SaveCMD { get; set; }
public ICommand LoadCMD { get; set; }
public ICommand ProgramCMD { get; set; }
public ICommand PrintCMD { get; set; }
public ICommand ExitCMD { get; set; }
// In MainVM constructor
ReadCMD = new RelayCommand(ReadSettings);
SaveCMD = new RelayCommand(SaveSettings);
LoadCMD = new RelayCommand(LoadSettings);
ProgramCMD = new RelayCommand(ProgramSettings);
PrintCMD = new RelayCommand(PrintSettings);
ExitCMD = new RelayCommand(ExitProgram);
繼電器的命令類:
public class RelayCommand : ICommand
{
private Action<object> execute;
private Predicate<object> canExecute;
private event EventHandler CanExecuteChangedInternal;
public RelayCommand(Action<object> execute)
: this(execute, DefaultCanExecute)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
{
throw new ArgumentNullException("execute");
}
if (canExecute == null)
{
throw new ArgumentNullException("canExecute");
}
this.execute = execute;
this.canExecute = canExecute;
}
public event EventHandler CanExecuteChanged
{
add
{
CommandManager.RequerySuggested += value;
this.CanExecuteChangedInternal += value;
}
remove
{
CommandManager.RequerySuggested -= value;
this.CanExecuteChangedInternal -= value;
}
}
public bool CanExecute(object parameter)
{
return this.canExecute != null && this.canExecute(parameter);
}
public void Execute(object parameter)
{
this.execute(parameter);
}
public void OnCanExecuteChanged()
{
EventHandler handler = this.CanExecuteChangedInternal;
if (handler != null)
{
//DispatcherHelper.BeginInvokeOnUIThread(() => handler.Invoke(this, EventArgs.Empty));
handler.Invoke(this, EventArgs.Empty);
}
}
public void Destroy()
{
this.canExecute = _ => false;
this.execute = _ => { return; };
}
private static bool DefaultCanExecute(object parameter)
{
return true;
}
}
UPDATE:
我從DockPanel
切換到StackPanel
並設置寬度與StatusBox
而不是允許LastChildFill
的調整狀態字段和這解決了我的問題。儘管我在StatusBox
的周圍放置了一個邊框以查看渲染的位置,但它仍然給我提出了問題。
請解釋屬性'SaveEnabled'等或張貼更多的代碼。如果缺少一半的綁定,很難在綁定中發現錯誤。 – lhildebrandt
@Ihildebrandt - 我爲您添加了SaveEnabled和ProgramEnabled屬性。 – Bluto
是否帶有'SaveEnabled'的按鈕,導致麻煩?順便說一句,你的'ICommand'實現是怎樣的? – XAMlMAX