wpf 使用MVVM Communitytoolkit更改按钮的前景或背景

xfyts7mz  于 2023-10-22  发布在  其他
关注(0)|答案(1)|浏览(124)

我是WPF和CommunityToolkit. Mvvm的新手。我开始构建一个基于WinForm设计的示例项目。我卡住的部分是设置一个单选按钮的前景和/或背景。我被告知并得到指示使用“样式”来做到这一点。XAML在Window中看起来是这样的。

<Window.Resources>
    <Style x:Key="GroupToggleStyle" TargetType="RadioButton" 
           BasedOn="{StaticResource {x:Type ToggleButton}}">
        <Setter Property="Foreground" Value="Blue"/>
        <Style.Triggers>
                <DataTrigger Binding="{Binding IsErrorProcess, RelativeSource={RelativeSource Self}}" 
                         Value="True">
                <DataTrigger.Setters>
                    <Setter Property="Foreground" Value="Red"/>
                </DataTrigger.Setters>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

单选按钮的XAML代码:

<RadioButton GroupName="btnErrorLog"
             Command="{Binding OpenError}"
             Content="{Binding ErrorText}"
             Width="80"
             IsEnabled="{Binding IsProcessingData}"
             Margin="5" HorizontalAlignment="Left"
             VerticalAlignment="Center"
             Style="{StaticResource GroupToggleStyle}" />

这将改变文本/内容的单选按钮时,点击“红色”。然而,我特灵让按钮前台(在这个时候)改变为“红色”只有当公共属性“IsErrorProcess”更改为“真”。我相信我有两个“风格”和“单选按钮”的约束力正确。
我的问题是。当我将IsErrorProcess设置为true时,我不知道如何将前景的颜色设置为红色。
我的MainWindowViewModel.cs代码:(我不得不删除真实的客户数据文件)

using CommunityToolkit.Mvvm.ComponentModel;
    using CommunityToolkit.Mvvm.Input;
    using CommunityToolkit.Mvvm.Messaging;
    using ImporterMessaging;
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.Drawing;
    using System.IO;
    using System.Threading.Tasks;
    using System.Windows.Documents;
    using System.Windows.Media;
    using Wpsi.CorrelDataImporter;

    namespace CorelImporter
    {
        public class MainWindowViewModel : ObservableRecipient
        {
        #region Variables/Fields
        private string _importFileName = string.Empty;
        private int _digitLength;
        private string _filterString = string.Empty;
        private List<CorrelUserRecord> _correlUserData = new List<CorrelUserRecord>();
        private List<string> _afterData = new List<string>();
        private List<string> _beforeData = new List<string>();
        private ObservableObject _count;
        private string _processingText;
        private bool _isProcessingData;
        private string _statusMessage;
                private string _errorText;
                private bool _isErrorProcess;
        public Brush btnErrorColor;
        #endregion

        #region RelayCommands
        public AsyncRelayCommand ProcessData { get; set; }
        public AsyncRelayCommand OpenError { get; set; }
        #endregion

        #region Properties
        public string ImportFileName
        {
            get => _importFileName;
            set
            {
                if (_importFileName == value)
                {
                    return;
                }
                _importFileName = value;
                OnPropertyChanged(nameof(ImportFileName));
            }
        }
        public string FilterString
        {
            get => _filterString;
            set
            {
                if (_filterString == value)
                {
                    return;
                }
                _filterString = value;
                OnPropertyChanged(nameof(FilterString));
            }
        }
        public List<CorrelUserRecord> CorrelUserData
        {
            get => _correlUserData;
            set
            {
                if (_correlUserData == value)
                {
                    return;
                }
                _correlUserData = value;
                OnPropertyChanged(nameof(CorrelUserData));
            }
        }
        public List<string> AfterData
        {
            get => _afterData;
            set
            {
                if (_afterData == value)
                {
                    return;
                }
                _afterData = value;
                OnPropertyChanged(nameof(AfterData));
            }
        }
        public List<string> BeforeData
        {
            get => _beforeData;
            set
            {
                if (_beforeData == value)
                {
                    return;
                }
                _beforeData = value;
                OnPropertyChanged(nameof(BeforeData));
            }
        }
        public int DigitLength
        {
            get => _digitLength;
            set
            {
                if (_digitLength == value)
                {
                    return;
                }
                _digitLength = value;
                OnPropertyChanged(nameof(DigitLength));
            }
        }
        public ObservableObject Count
        {
            get => _count;
            set
            {
                if (_count == value)
                    return;
                _count = value;
                OnPropertyChanged(nameof(Count));

            }
        }
        public bool IsChecked
        {
            get => Globals.IsChecked;
            set
            {
                if (Globals.IsChecked == value)
                    return;
                Globals.IsChecked = value;
                OnPropertyChanged(nameof(IsChecked));
            }
        }
        public bool IsProcessingData
        {
            get => _isProcessingData;
            set
            {
                if (_isProcessingData == value)
                    return;
                _isProcessingData = value;
                OnPropertyChanged(nameof(IsProcessingData));
            }
        }
        public string ProcessingText
        {
            get => _processingText;
            set
            {
                if (_processingText== value)
                    return;
                _processingText = value;
                OnPropertyChanged(nameof(ProcessingText));
            }
        }
        public string StatusMessage
        {
            get => _statusMessage;
            set
            {
                if (_statusMessage == value)
                    return;
                _statusMessage = value;
                OnPropertyChanged(nameof(StatusMessage));
            }
        }
        public string ErrorText
        {
            get => _errorText;
            set
            {
                if (_errorText == value)
                    return;
                _errorText = value;
                OnPropertyChanged(nameof(ErrorText));
            }
        }
        public bool IsErrorProcess
        {
            get => _isErrorProcess;
            set
            {
                if (_isErrorProcess == value)
                    return;
                _isErrorProcess = value;
                OnPropertyChanged(nameof(IsErrorProcess));
                btnErrorColor = Brushes.Red;
                OnPropertyChanged(nameof(btnErrorColor));
            }
        }
        #endregion

        public MainWindowViewModel()
        {
            ImportFileName = Path.Combine(CorrelDataImporter.ImportExportPath, @"");
            DigitLength = 11;
            FilterString = "+1214648";
            AfterData.Add("AFTER NOT DATA LOADED");
            BeforeData.Add("BEFORE NOT DATA LOADED");
            ProcessingText = "Click To Process";
            ErrorText = "Error Log";
            IsProcessingData = true;
            IsErrorProcess = true;
            StatusMessage = string.Empty;
            //Count = 0.ToString();

            ProcessData = new AsyncRelayCommand(OnProcessDataExecute, () => true);
            OpenError = new AsyncRelayCommand(OnOpenErrorExecute, () => true);

            // Register a message in some module
            WeakReferenceMessenger.Default.Register<CorrelImporterStatusMessages>(this, (r, m) =>
            {
                // Handle the message here, with r being the recipient and m being the
                // input message. Using the recipient passed as input makes it so that
                // the lambda expression doesn't capture "this", improving performance.
                UpdateStatusMessage(m.Value);
            });
            WeakReferenceMessenger.Default.Register<UpdateBeforeDataList>(this, (r, m) =>
            {
                // Handle the message here, with r being the recipient and m being the
                // input message. Using the recipient passed as input makes it so that
                // the lambda expression doesn't capture "this", improving performance.
                UpdateBeforeList(m.Value);
            });
            WeakReferenceMessenger.Default.Register<UpdateAfterDataList>(this, (r, m) =>
            {
                // Handle the message here, with r being the recipient and m being the
                // input message. Using the recipient passed as input makes it so that
                // the lambda expression doesn't capture "this", improving performance.
                UpdateAfterList(m.Value);
            });
            //WeakReferenceMessenger.Default.Register<ErrorButtonColor>(this, (r, m) =>
            //{
            //  // Handle the message here, with r being the recipient and m being the
            //  // input message. Using the recipient passed as input makes it so that
            //  // the lambda expression doesn't capture "this", improving performance.
            //  IsErrorProcess(m.Value);
            //});
        }
        private void UpdateBeforeList(List<string> value)
        {
            BeforeData = value;
        }
        private void UpdateAfterList(List<string> value)
        {
            AfterData = value;
        }
        private void UpdateStatusMessage(string statusMessage)
        {
            StatusMessage = statusMessage;
        }
        //private void ErrorButtonColor(System.Drawing.Color value)
        //{
        //  IsErrorProcess.f = Color.Red;
        //}
        private async Task OnProcessDataExecute()
        {
            if (Globals.IsChecked == true)
            {
                string sDeleteFile = $"{Globals.sAPPPath}\\{Globals.sApplicationName}" + ".log";
                if (File.Exists(sDeleteFile))
                    File.Delete(sDeleteFile);
                
                IsChecked = false;
            }

            IsProcessingData = false;
            ProcessingText = "Processing Data...";

            await LoadCorrelData();

            WeakReferenceMessenger.Default.Send(new CorrelImporterStatusMessages($"Process completed."));

            IsProcessingData = true;
            ProcessingText = "Click To Process";

            btnErrorColor = Brushes.Black;
            if (Globals.bErrorOn == true)
            {
                IsErrorProcess = true;
                btnErrorColor = Brushes.Red;
            }
        }

        private async Task OnOpenErrorExecute()
        {
            if(Globals.bErrorOn == true) 
            {
                IsErrorProcess= true;
                Process myProcess = new Process();
                string sGet = $"{Globals.sAPPPath}\\{Globals.sApplicationName}" + ".log";
                Process.Start("notepad.exe", sGet);

            }
        }
        public async Task LoadCorrelData()
        {
                    CorrelUserData = await CorrelDataImporter.ProcessCorrelData(Path.Combine(CorrelDataImporter.ImportExportPath, @""));

            //This program is much like Command Project but in WPF
            await CorrelDataImporter.ProcessAfterList(CorrelUserData, FilterString, DigitLength);
        }
    }
}

使用“CommunityToolkit.Mvvm.Messaging.Messages”。也有人建议我可以用这个方法来调用单选按钮的样式更改,但我不能工作出来。真实的不知道我在做什么没有工作样本。**我仍然不确定什么时候需要“风格”,而不是。**这里的帮助将不胜感激。
希望能有一个可行的解决办法。

vxbzzdmp

vxbzzdmp1#

您需要删除RelativeSource={RelativeSource Self},因为在这种情况下,Self表示RadioButton,而IsErrorProcess在ViewModel中,而不是在RadioButton中。
这是最小的代码,为我工作(更新RadioButtonForeground)。

<Window.Resources>
    <Style TargetType="RadioButton">
        <Setter Property="Foreground" Value="Blue" />
        <Style.Triggers>
            <DataTrigger
                Binding="{Binding IsErrorProcess}"
                Value="True">
                <DataTrigger.Setters>
                    <Setter Property="Foreground" Value="Red" />
                </DataTrigger.Setters>
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<StackPanel>
    <Button
        Command="{Binding TestCommand}"
        Content="Test" />
    <RadioButton Content="{Binding ErrorText}" />
</StackPanel>
public partial class MainWindowViewModel : ObservableObject
{
    [ObservableProperty]
    private bool isErrorProcess;

    [ObservableProperty]
    private string? errorText;

    [RelayCommand]
    private void Test()
    {
        IsErrorProcess = IsErrorProcess is false;
        ErrorText = IsErrorProcess is true
            ? "Error text"
            : string.Empty;
    }
}

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new MainWindowViewModel();
    }
}

相关问题