当 Bool 变量变为 True 时更改标签

问题描述 投票:0回答:3

我不太确定如何解释这一点...我将把代码放在伪代码中以便于阅读。

我非常希望标签在类的 bool 变量更改时更改其文本...我不确定我需要使用什么,因为我使用的是 WPF 并且该类不能只更改我不更改的标签不觉得吗?

我需要举办某种活动吗?或者 WPF 事件?感谢您的帮助。

public MainWindow()
{
   SomeClass temp = new SomeClass();

   void ButtonClick(sender, EventArgs e)
   {  
      if (temp.Authenticate)
        label.Content = "AUTHENTICATED";
   }
}

public SomeClass
{
  bool _authenticated;

  public bool Authenticate()
  {
    //send UDP msg
    //wait for UDP msg for authentication
    //return true or false accordingly
  }
}
c# wpf events delegates event-handling
3个回答
8
投票

除了 BradleyDotNet 的答案之外,另一种 WPF 方法是使用触发器。这将纯粹基于 XAML,无需转换器代码。

XAML:

<Label>
  <Label.Style>
    <Style TargetType="Label">
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsAuthenticated}" Value="True">
          <Setter Property="Content" Value="Authenticated" />
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Label.Style>
</Label>

适用与 BradledDotNet 提到的相同规则,应附加 ViewModel,并且“IsAuthenticated”属性应引发 PropertyChanged 事件。

-- 按照 Gayot Fow 的建议添加一些样板代码 --

查看背后代码:

为了简单起见,我将在后面的代码中设置视图的 DataContext。为了获得更好的设计,您可以使用 ViewModelLocator,如此处所述。

public partial class SampleWindow : Window
{
  SampleModel _model = new SampleModel();

  public SampleWindow() {
    InitializeComponent();
    DataContext = _model; // attach the model/viewmodel to DataContext for binding in XAML
  }
}

示例模型(实际上应该是ViewModel):

这里的要点是附加的模型/视图模型必须实现 INotifyPropertyChanged。

public class SampleModel : INotifyPropertyChanged
{
  bool _isAuthenticated = false;

  public bool IsAuthenticated {
    get { return _isAuthenticated; }
    set {
      if (_isAuthenticated != value) {
        _isAuthenticated = value;
        OnPropertyChanged("IsAuthenticated"); // raising this event is key to have binding working properly
      }
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;

  void OnPropertyChanged(string propName) {
    if (PropertyChanged != null) {
      PropertyChanged(this, new PropertyChangedEventArgs(propName));
    }
  }
}

4
投票

由于我们使用 WPF,我将使用绑定和转换器来完成此操作:

<Page.Resources>
   <local:BoolToAuthenticationStringConverter x:Key="BoolToAuthenticationStringConverter"/>
</Page>

<Label Content="{Binding Path=IsAuthenticated, Converter={StaticResource BoolToAuthenticationStringConverter}"/>

然后是一个转换器,如下所示:

public class BoolToAuthenticationStringConverter : IValueConverter
{
   public object Convert (...)
   {
      if ((bool)value)
         return "Authenticated!";
      else
         return "Not Authenticated!";
   }

   public object ConvertBack (...)
   {
      //We don't care about this one for this converter
      throw new NotImplementedException();
   }
}

在我们的 XAML 中,我们在资源部分声明转换器,然后将其用作“Content”绑定的“Converter”选项。在代码中,我们将

value
转换为 bool(
IsAuthenticated
假定为 ViewModel 中的 bool),并返回适当的字符串。确保您的 ViewModel 实现
INotifyPropertyChanged
并且
IsAuthenticated
引发
PropertyChanged
事件才能正常工作!

注意: 由于您不会通过 UI 更改

Label
,因此您无需担心
ConvertBack
。您可以将模式设置为
OneWay
以确保它永远不会被调用。

当然,这是针对该场景的。我们可以做一个通用的:

<Label Content="{Binding Path=IsAuthenticated, Converter={StaticResource BoolDecisionToStringConverter}, ConverterParameter='Authenticated;Not Authenticated'}"/>

然后是一个转换器,如下所示:

public class BoolDecisionToStringConverter : IValueConverter
{
   public object Convert (...)
   {
      string[] args = String.Split((String)parameter, ';');
      if ((bool)value)
         return args[0];
      else
         return args[1];
   }

   public object ConvertBack (...)
   {
      //We don't care about this one for this converter
      throw new NotImplementedException();
   }
}

2
投票

是的,您需要一个活动。

考虑这样的示例:

public SomeClass {
    public event EventHandler<EventArgs> AuthenticateEvent;  
    boolean isAuthenticated;

    public bool Authenticate()
    {
        // Do things
        isAuthenticated = true;
        AuthenticateEvent(this, new EventArgs());
    }
}

public MainWindow()
{
   SomeClass temp = new SomeClass();

   public MainWindow(){
      temp.AuthenticateEvent+= OnAuthentication;
      temp.Authenticate();
   }

   private void OnAuthentication(object sender, EventArgs e){
       Dispatcher.Invoke(() => {
           label.Content = "AUTHENTICATED";
       }); 
   }
}

现在,每当

temp
触发
Authenticate
事件时,它都会更改您的标签。

© www.soinside.com 2019 - 2024. All rights reserved.