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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23641688/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:43:23  来源:igfitidea点击:

Changing a Label when a Bool variable turns True

c#wpfeventsdelegatesevent-handling

提问by user1189352

i'm not really sure how to explain this... i'm going to put the code in psuedo code for easy reading

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

pretty much I want a label to change it's text when a bool variable of a class changes... i'm not sure what I need to use since i'm using WPF and the class can't just change the label i don't think?

几乎我想要一个标签在类的 bool 变量更改时更改它的文本...我不确定我需要使用什么,因为我使用的是 WPF 并且该类不能只更改我不使用的标签'不觉得?

do i need some sort of event? or a WPF event? thanks for any help

我需要某种活动吗?还是 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
  }
}

回答by techhero

Another WPF approach other than BradledDotNet answer is to use triggers. This will be purely XAML based without converter code.

除了 BradledDotNet 答案之外,另一种 WPF 方法是使用触发器。这将完全基于 XAML,没有转换器代码。

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>

Same rule applies as mentioned by BradledDotNet, ViewModel should be attached and "IsAuthenticated" property should raise the PropertyChanged event.

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

-- Add some boilerplate code as suggested by Gayot Fow --

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

View Code Behind:

查看后面的代码:

For simplicity I will just set the DataContext of the view in code behind. For a better design you can use ViewModelLocator as explained here.

为简单起见,我将在后面的代码中设置视图的 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
  }
}

Example Model(it should really be ViewModel):

示例模型(它应该是 ViewModel):

The main point here is the attached model/viewmodel has to implement INotifyPropertyChanged.

这里的要点是附加的模型/视图模型必须实现 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));
    }
  }
}

回答by BradleyDotNET

Since we are using WPF, I would use a binding and converter to accomplish this:

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

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

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

Then a converter that looks like:

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

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();
   }
}

In our XAML, we declare the converter in the resources section, then use it as the "Converter" option of the binding for "Content". In the code, we cast valueto a bool (IsAuthenticatedis assumed to be a bool in your ViewModel), and return an appropriate string. Make sure your ViewModel implements INotifyPropertyChangedand that IsAuthenticatedraises the PropertyChangedevent for this to work!

在我们的 XAML 中,我们在资源部分声明转换器,然后将其用作“内容”绑定的“转换器”选项。在代码中,我们value转换为 bool(IsAuthenticated假定为您的 ViewModel 中的 bool),并返回适当的字符串。确保您的 ViewModel 实现INotifyPropertyChangedIsAuthenticated引发PropertyChanged事件以使其正常工作!

Note:Since you won't be changing the Labelvia the UI, you don't need to worry about ConvertBack. You could set the mode to OneWayto make sure that it never gets called though.

注意:由于您不会Label通过 UI更改,因此您无需担心ConvertBack. 您可以将模式设置为OneWay以确保它永远不会被调用。

Granted, this is very specific to this scenario. We could make a generic one:

当然,这是非常特定于这种情况的。我们可以做一个通用的:

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

Then a converter that looks like:

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

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();
   }
}

回答by Jeroen Vannevel

Yes, you need an event.

是的,你需要一个事件。

Consider a sample like this:

考虑这样的示例:

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";
       }); 
   }
}

Now whenever tempfires the Authenticateevent, it will change your label.

现在,无论何时temp触发该Authenticate事件,它都会更改您的标签。