Tengo el siguiente código;

public partial class MainWindow : Window, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        bool _myValue;
        public bool myValue
        {
            get { return _myValue; }
            set {
                _myValue = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("myValue"));
            }
        }

        public MainWindow() {
            myValue = false;
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromSeconds(1);
            timer.Tick += timer_Tick;
            timer.Start();
        }

        void timer_Tick(object sender, EventArgs e) { 
            myValue = !myValue;
            lblTime.Content = myValue.ToString();
        }
    }

Y el correspondiente xaml:

    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BoolToVis" />
    </Window.Resources>
    <DockPanel Margin="10">
        <Button x:Name="HideMe"
             Height="50" Width="50"
            Cursor="Hand" 
            Visibility="{Binding Path=myValue, Converter={StaticResource BoolToVis}}"/>
        <Label x:Name="lblTime" />
    </DockPanel>

Lo que estoy tratando de hacer es actualizar la visibilidad del botón con cada timer_tick; La etiqueta se actualiza, pero el enlace se niega a funcionar.

Estoy muy seguro de que hay un descuido, pero después de seguir numerosos tutoriales, no hay ninguno sobre cómo puedo hacer que esto funcione ... la mayoría funciona con una casilla de verificación en el WPF; pero necesito el booleano en el código detrás para enviar a controlar la visibilidad del botón, una vez que se actualiza ...

1
Fimlore 14 feb. 2020 a las 17:31

2 respuestas

La mejor respuesta

Establezca el DataContext de la ventana en sí mismo y no olvide llamar InitializeComponent():

public MainWindow()
{
    InitializeComponent();
    DataContext = this; //<--

    myValue = false;
    DispatcherTimer timer = new DispatcherTimer();
    timer.Interval = TimeSpan.FromSeconds(1);
    timer.Tick += timer_Tick;
    timer.Start();
}
1
mm8 14 feb. 2020 a las 14:45

Mm8 le dio la respuesta perfecta a su pregunta (estableciendo el contexto de datos): solo quiero señalar una pequeña cosa que debería hacer que su vida sea mucho más fácil al construir sus propiedades.

Podemos crear una función para activar el evento de cambio de propiedad, requiriendo que solo escriba "OnPropertyChanged ()" para activar la actualización de la interfaz de usuario. Para hacer esto, vamos a agregar el 'vacío' a continuación, diciéndole que use una propiedad llamada "Nombre del miembro llamante" de forma predeterminada, a menos que proporcione manualmente un nombre de propiedad (I.E. OnPropertyChanged ("SomeOtherValue");).

Para hacer esto, primero debemos agregar una declaración de uso en la parte superior de su clase UserViewModel:

using System.Runtime.CompilerServices;

Luego, agregaremos el código OnPropertyChanged e incluiremos el 'nombre del miembro llamante' Debería verse así:

    private void OnPropertyChanged([CallerMemberName] String name = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }

Ahora, actualizaremos su propiedad para usar el método simplificado:

   public bool myValue
   {
     get { return _myValue; }
     set
     {
            _myValue = value;
            OnPropertyChanged();
     }
}

Por último, personalmente prefiero una forma simplificada para obtener / configurar: lo que estás haciendo está completamente bien y no hay necesidad de cambiarlo si no quieres, pero te sugiero que lo pruebes de esta manera para ver como te gusta :)

    public bool MyValue
    {
        get => _myValue; 
        set
        {
            // If the value hasn't changed, the code will return (Exit) - avoiding a false property changed trigger :) 
            if (_myValue == value) return;
            _myValue = value;
            OnPropertyChanged(); 
        }
    }

Motivos: Verificar si el valor realmente ha cambiado en su SET evitará disparadores falsos, usa menos corchetes, ¡e intellisense hace que escribir esto sea súper fácil!

¡Hazme saber si tienes alguna pregunta!

0
Nik P 14 feb. 2020 a las 15:17