Entwickler-Ecke

WPF / Silverlight - DataTrigger wird nicht ausgeführt


Greenberet - Mo 12.03.18 20:03
Titel: DataTrigger wird nicht ausgeführt
Hallo,

ich arbeite seit langem mal wieder mit WPF und habe ein Problem mit einem DataTrigger auf einem Enum um ein anderes Bild anzuzeigen

Ziel ist es in dem Control den Status eines Windows Dienstes anzuzeigen.

Laut Debugger wird der Status richtig gesetzt, aber in der GUI wird das Bild nie aktualisiert.


XML-Daten
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
<UserControl x:Class="ServiceStatus.ServiceControl"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:ServiceStatus"
             xmlns:service="clr-namespace:System.ServiceProcess;assembly=System.ServiceProcess"
             mc:Ignorable="d" 
             d:DesignHeight="50" d:DesignWidth="60"
             Loaded="UserControl_Loaded"
             >
    <StackPanel Orientation="Horizontal">
        <Image Stretch="Fill" Panel.ZIndex="1"  Width="16" Height="16" Source="StatusNo.png">
            <Image.Style>
                <Style TargetType="{x:Type Image}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=Status}" Value="{x:Static service:ServiceControllerStatus.Stopped}">
                            <Setter Property="Source" Value="StatusNo.png"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=Status}" Value="{x:Static service:ServiceControllerStatus.Running}">
                            <Setter Property="Source" Value="StatusOK.png"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
    </StackPanel>
</UserControl>



C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
    public partial class ServiceControl : UserControl
    {
        private ServiceController _serviceController;

        public ServiceControllerStatus Status
        {
            get { return (ServiceControllerStatus)GetValue(StatusProperty); }
            set
            {
                SetValue(StatusProperty, value);
            }
        }

        // Using a DependencyProperty as the backing store for Status.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty StatusProperty =
            DependencyProperty.Register("Status"typeof(ServiceControllerStatus), typeof(ServiceControl), new PropertyMetadata(ServiceControllerStatus.Stopped));
        private void initController()
        {
            if (string.IsNullOrEmpty(ServerName) || string.IsNullOrEmpty(ServiceName))
                return;

            _serviceController = new ServiceController(ServiceName, ServerName);
            Status = _serviceController.Status;
        }
}


Th69 - Mo 12.03.18 21:26

Hallo,

in wpf datatrigger on an image source [https://stackoverflow.com/questions/2414358/wpf-datatrigger-on-an-image-source] hatte jemand ein ähnliches Problem: entferne mal die Source aus dem Image-Tag.


Greenberet - Di 13.03.18 14:08

Hallo,

das hat leider nichts gebracht =(

Laut LiveView bleibt Source immer leer.


Palladin007 - Di 13.03.18 14:34

Wie setzt Du den DataContext?

Du hast die Property als DependencyProperty im Control definiert, daher vermute ich, dass Du MVVM nicht ganz verstanden hast.
Das Problem wird daher sein, dass der DataContext, wo WPF die Status-Property sucht, immer null ist. Entsprechend findet er die Status-Property nicht und kann ihren Wert im Trigger nicht vergleichen.

Die schnellste und einfache Lösung wäre, wenn Du das Control selber als DataContext setzt, also im Konstruktor DataContext = this; schreibst.
Das ist aber eigentlich nicht richtig so, auch wenn es funktionieren würde.

Die bessere Lösung wäre ein ViewModel, was die Status-Property und auch die restliche Logik enthält. Das ViewModel setzt Du dann als DataContext und dann funktioniert auch dein Trigger.


Greenberet - Di 13.03.18 14:58

user profile iconPalladin007 hat folgendes geschrieben Zum zitierten Posting springen:
Sie setzt Du den DataContext?

Du hast die Property als DependencyProperty im Control definiert, daher vermute ich, dass Du MVVM nicht ganz verstanden hast.
Das Problem wird daher sein, dass der DataContext, wo WPF die Status-Property sucht, immer null ist. Entsprechend findet er die Status-Property nicht und kann ihren Wert im Trigger nicht vergleichen.

Die schnellste und einfache Lösung wäre, wenn Du das Control selber als DataContext setzt, also im Konstruktor DataContext = this; schreibst.
Das ist aber eigentlich nicht richtig so, auch wenn es funktionieren würde.

Die bessere Lösung wäre ein ViewModel, was die Status-Property und auch die restliche Logik enthält. Das ViewModel setzt Du dann als DataContext und dann funktioniert auch dein Trigger.


DataContext war das richtige Stichwort. Danke =)

Das ViewModel werde ich mir ein anderes mal ansehen. Fürs erste reicht mir der QuickFix mit dem Datacontext = this.