我的 WPF 应用程序中有一个页面。我需要一个可以激活和停用的按钮。它实际上可以工作,但是当它激活时,我在屏幕上看不到它。如果我打开另一个页面,然后再次打开我的页面,它就会变为活动状态。
用户控制代码:
<UserControl x:Class="MediaAuthentication.UserControls.LandingFooterUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:MediaAuthentication.UserControls"
xmlns:vm="clr-namespace:MediaAuthentication.ViewModels"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=vm:LandingFooterViewModel}"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Button Content="Apply"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Width="200" Height="50"
IsEnabled="{Binding IsButtonEnabled}"
Command="{Binding ButtonCommand}" />
</Grid>
</UserControl>
ViewModel代码:
using MediaAuthentication.Models;
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using MediaAuthentication.Business.Services.Logging;
using MediaAuthentication.Business.Services.Metadata;
namespace MediaAuthentication.ViewModels
{
public class LandingFooterViewModel
{
private ILoggerService _loggerService;
private IVideoMetadataService _videoMetadataService;
private MetaDataFooterViewModel _metaFooterViewModel;
public int markBeginning = -1;
public int markEnd = -1;
private bool _isButtonEnabled;
public bool IsButtonEnabled
{
get => _isButtonEnabled;
set
{
if (_isButtonEnabled != value)
{
_isButtonEnabled = value;
OnPropertyChanged(nameof(IsButtonEnabled));
(ButtonCommand as RelayCommand)?.RaiseCanExecuteChanged();
}
}
}
// ICommand Property
public ICommand ButtonCommand { get; }
public LandingFooterViewModel(ILoggerService loggerService, IVideoMetadataService videoMetadataService, MetaDataFooterViewModel metaFooterViewModel)
{
_loggerService = loggerService;
_videoMetadataService = videoMetadataService;
_metaFooterViewModel = metaFooterViewModel;
IsButtonEnabled = false;
ButtonCommand = new RelayCommand(OnButtonClicked, () => IsButtonEnabled);
}
private void OnButtonClicked()
{
Storage.firstFrameIndex = markBeginning;
Storage.lastFrameIndex = markEnd;
if (Storage.media == null || string.IsNullOrEmpty(Storage.path))
{
_loggerService.LogWarning("No media file loaded. Please upload a file first.");
return;
}
//IsLoading = true;
try
{
if (Storage.media.StreamList != null)
{
foreach (var stream in Storage.media.StreamList)
{
stream.FrameList.Clear();
}
Storage.media.StreamList.Clear();
}
_videoMetadataService.ExtractMetadata(Storage.media);
_metaFooterViewModel.UpdateMetadata(Storage.media);
_loggerService.LogInfo("Metadata extraction completed successfully.");
_metaFooterViewModel.UpdateMetadata(Storage.media);
/*
List<string> frameTypes = new List<string>();
foreach (Frame frame in media.StreamList[0].FrameList)
{
frameTypes.Add(frame.Metadata[FrameMetadataKey.FrameType]);
} */
}
catch (Exception ex)
{
_loggerService.LogError($"Error extracting metadata: {ex.Message}");
}
finally
{
// IsLoading = false;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
我在 IsButtonEnabled 行中插入了一个断点,但是它工作正常。每当我想更改按钮的活动时,断点就会起作用并且该布尔变量的值是正确的。
WPF 绑定依赖于 INotifyPropertyChanged 来检测底层数据的更改。当您在属性设置器中引发 PropertyChanged 事件时,WPF 的绑定系统会侦听该事件并相应地更新 UI。
您实现了接口,但没有用它标记类:
public class LandingFooterViewModel : INotifyPropertyChanged