none
C# UWP MVVM UserControl deaktivieren RRS feed

  • Frage

  • Hi,

    ich habe ein UserControl:

    <UserControl
        x:Class="HelloWindowsIot.Controls.ClockControl"
        <Grid>
            <TextBlock Text="{x:Bind ViewModel.CurrentTime, Converter={StaticResource TimeStringFormatConverter},Mode=OneWay}" FontSize="36" FontFamily="Cambria"/>
        </Grid>
    </UserControl>
    public sealed partial class ClockControl : UserControl
        {
            public ClockViewModel ViewModel { get; set; }
    
            public ClockControl()
            {
                this.InitializeComponent();
                this.ViewModel = new ClockViewModel();
    
            }
        }

    ViewModel:

    public class ClockViewModel: BindableBase
        {
            private DispatcherTimer _timer = new DispatcherTimer();
            public DateTime CurrentTime { get { return DateTime.Now; } }
    
            public ClockViewModel()
            {
                _timer.Tick += Timer_Tick;
                _timer.Interval = new TimeSpan(0, 0, 1);
                _timer.Start();
            }
    
            private void Timer_Tick(object sender, object e)
            {
                this.OnPropertyChanged("CurrentTime");
            }
    
        }

    Dann habe ich ein ViewModel "DashBoard" wo ich Einstellungen lade:

    // <summary>
            /// Load Settings for the ViewModel
            /// </summary>
            public async Task LoadData()
            {
                try
                {
                    var s = await Dal.GetSetup();
                    EnableClock = s.EnableClock;
                }
                catch { }
            }

    DashBoard :

    <StackPanel  Grid.Row="0" Orientation="Vertical">
                        <uc:ClockControl Visibility="{x:Bind ViewModel.EnableClock, Converter={StaticResource BoolToVisibility}}" />
                    </StackPanel>

    Wenn meine Eigenschaft ClockEnable=False ist, möchte ich das UserControl nicht angezeigt bekommen.

    Das klappt auch mit Visibility, aber im Hintergrund wird trotzdem das ClockViewModel initialisiert.Ich möchte nicht das der DIspatcherTimer läuft wenn das Control nicht angezeigt wird.

    Wie löse ich das am besten? Muss ich CurrentTime vom DashBoard ViewModel an das UserControl übergeben (Dependency propertys) ? Oder das Control "removen"?

    if (Visibility == Visibility.Collapsed)
    ((StackPanel)this.Parent).Children.Remove(this);

    Wobei der Coder durchlaufen wird, aber mein Dispatcher im ClockViewMOdel trotzdem weiter laeuft.

    Vielen Dank



    • Bearbeitet elTorito Donnerstag, 28. März 2019 19:26
    Donnerstag, 28. März 2019 19:25

Antworten

  • Hi,
    mit dem _timer.Start läuft ein separater Thread los. Dem Thread ist es egal, was da in anderen Threads passiert. Wenn Du nicht willst, dass er weiterläuft, musst Du ihn beenden und ggf. später neu starten.

    --
    Viele Grüsse / Best Regards
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    • Als Antwort markiert elTorito Donnerstag, 28. März 2019 19:57
    Donnerstag, 28. März 2019 19:33

Alle Antworten

  • Hi,
    mit dem _timer.Start läuft ein separater Thread los. Dem Thread ist es egal, was da in anderen Threads passiert. Wenn Du nicht willst, dass er weiterläuft, musst Du ihn beenden und ggf. später neu starten.

    --
    Viele Grüsse / Best Regards
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    • Als Antwort markiert elTorito Donnerstag, 28. März 2019 19:57
    Donnerstag, 28. März 2019 19:33
  • Ok. Mache ich dann wie folgt, oder gibt es eine bessere Methode?

    Dem UserControl gebe ich EnableClock via DependencyProiperty rein:

    <uc:ClockControl EnableClock="{x:Bind ViewModel.EnableClock}" Visibility="{x:Bind ViewModel.EnableClock, Converter={StaticResource BoolToVisibility}}" />

    Im UserControl setze ich die Eigenschaft aufs ViewModel:

     public sealed partial class ClockControl : UserControl
        {
            public ClockViewModel ViewModel { get; set; }
    
            public bool EnableClock
            {
                get => (bool)GetValue(EnableClockProperty);
                set => SetValue(EnableClockProperty, value);
            }
            public static readonly DependencyProperty EnableClockProperty =
                DependencyProperty.Register("EnableClockProperty", typeof(bool), typeof(ClockControl), new PropertyMetadata(false));
    
            public ClockControl()
            {
                this.InitializeComponent();
                this.ViewModel = new ClockViewModel();
                this.ViewModel.EnableClock = EnableClock;
            }
        }

    Im ViewModel frage ich dann im Ticker ab ob die Uhr Enabled sein muss:

    public class ClockViewModel: BindableBase
        {
            private DispatcherTimer _timer = new DispatcherTimer();
            public DateTime CurrentTime { get { return DateTime.Now; } }
            public ClockViewModel()
            {
                _timer.Tick += Timer_Tick;
                _timer.Interval = new TimeSpan(0, 0, 1);
                _timer.Start();
            }
    
            private bool enableClock;
            public bool EnableClock
            {
                get { return this.enableClock; }
                set { this.SetProperty(ref this.enableClock, value); }
            }
    
            private void Timer_Tick(object sender, object e)
            {
                if (enableClock == false)
                    _timer.Stop();
                else
                    this.OnPropertyChanged("CurrentTime");
            }
        }

    Vielen Dank

    Donnerstag, 28. März 2019 19:57
  • Hi,
    ich denke, dass das eine akzeptable Möglichkeit ist. Alternativ wäre auch das Abfangen eine Ereignisses mittels Interactivity möglich, in welchem dann doe booleasche Variable zum Beenden mit Time.Stop gesetzt wird.

    --
    Viele Grüsse / Best Regards
    Peter Fleischer (former MVP for Developer Technologies)
    Homepage, Tipps, Tricks

    Donnerstag, 28. März 2019 21:01