datatrigger บน enum เพื่อเปลี่ยนภาพ


103

ฉันมีปุ่มที่มีภาพพื้นหลังคงที่และต้องการแสดงภาพซ้อนทับขนาดเล็กที่ด้านบน ภาพซ้อนทับที่จะเลือกขึ้นอยู่กับคุณสมบัติการอ้างอิง ( LapCounterPingStatus) ของโมเดลตามมุมมอง

นี่คือสิ่งที่ฉันได้รับจนถึงตอนนี้:

<Button>
    <Grid>
        <Image Stretch="None"> <!-- Background Image -->
            <Image.Style>
                <Style TargetType="{x:Type Image}">
                    <Setter Property="Source" Value="/Images/Pingn.png"/>
                </Style>
            </Image.Style>
        </Image>
        <Image Stretch="None" Panel.ZIndex="1"> <!-- Small Overlay Image -->
            <Image.Style>
                <Style TargetType="{x:Type Image}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="PingStatus.PING_UNKNOWN">
                            <Setter Property="Source" Value="/Images/RefreshOverlayn.png"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="PingStatus.PING_FAILURE">
                            <Setter Property="Source" Value="/Images/ErrorOverlayn.png"/>
                        </DataTrigger>
                        <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="PingStatus.PING_SUCCESS">
                            <Setter Property="Source" Value="/Images/CheckmarkOverlayn.png"/>
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Image.Style>
        </Image>
    </Grid>
</Button>

ส่วนที่เกี่ยวข้องของโมเดลมุมมองของฉัน

public class ConfigurationViewModel
{
    public enum PingStatus { PING_UNKNOWN, PING_SUCCESS, PING_FAILURE };

    public PingStatus LapCounterPingStatus
    {
        get { return _lapCounterPingStatus; }
        set
        {
            _lapCounterPingStatus = value;
            RaisePropertyChanged(LapCounterPingStatusPropertyName);
        }
    }
}

ตอนนี้ไม่มีการแสดงภาพซ้อนทับเลย มีอะไรผิดปกติ?


อัปเดต

หน้าต่างร่องรอยของ IDE ของฉันคือการแสดงและSystem.ArgumentException System.FormatExceptionแหล่งที่มาของปัญหาอาจเป็นประเภทของการแจงนับที่ไม่รู้จักของPingStatusXAML หรือไม่


ที่เกี่ยวข้อง: stackoverflow.com/q/10250925/590790แม้ว่าผู้ชายคนนี้จะใช้งานได้แล้ว
Steven Jeuris

คำตอบ:


251

คุณต้องมี 2 สิ่งในการทำงานนี้:

1 - เพิ่มการxmlnsอ้างอิงในองค์ประกอบรากของไฟล์ XAML ของคุณไปยังเนมสเปซที่กำหนด Enum ของคุณ:

<UserControl ...
xmlns:my="clr-namespace:YourEnumNamespace;assembly=YourAssembly"> 

2 - ในValueคุณสมบัติของDataTriggerใช้{x:Static}แบบฟอร์ม:

 <DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="{x:Static my:PingStatus.PING_UNKNOWN}">

โปรดสังเกตว่าประเภท Enum ต้องขึ้นต้นด้วยคำนำหน้า xmlns ที่คุณกำหนดไว้ข้างต้น

แก้ไข:

หาก Enum ของคุณถูกประกาศภายในคลาสคุณจำเป็นต้องใช้ไวยากรณ์:

{x:Static namespace:ClassName+EnumName.EnumValue}

ตัวอย่างเช่น:

{x:Static my:ConfigurationViewModel+PingStatus.PING_UNKNOWN}


1
ฉันเพิ่มxmlnsเช่นนี้และทริกเกอร์เช่นนั้นxmlns:local="clr-namespace:MyCompany.Testbench" ไม่มีฉันได้รับข้อผิดพลาด<DataTrigger Binding="{Binding Path=LapCounterPingStatus}" Value="{x:Static local:PingStatus.PING_UNKNOWN}"> Cannot find the type 'PingStatus'
nabulke

1
enum PingStatusMyCompany.TestBench.ConfigurationViewModelถูกกำหนดให้อยู่ภายในชั้นเรียน ฉันต้องเพิ่มชื่อชั้นเรียนที่ไหน?
nabulke

3
ขอบคุณ. ฉันไม่พบไวยากรณ์ของประเภทที่ซ้อนกันที่ใดก็ได้ ไวยากรณ์ "+" อยู่ที่ไหน ฉันไม่พบใน MSDN หรือในหนังสือ WPF ที่ฉันมี ฉันคิดว่ามันควรอยู่ในx: Static Markup Extensionแต่ไม่ใช่
skst

1
@skst สัญลักษณ์ + แยกความแตกต่างของประเภทที่มีจากเนมสเปซที่ซ้อน Type t = typeof (System.Environment.SpecialFolder); Console.WriteLine (t.FullName); // prints System.Environment+SpecialFolder


3

ตัวอย่างการทำงานที่สมบูรณ์สำหรับ WPF + MVVM

ผ่านการทดสอบ MSVC 2017

ในมุมมอง:

<TextBlock Text="Some text to be colored by an enum">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding StatusIcon}" Value="{x:Static my:StatusIcon.Warning}">
                    <Setter Property="Foreground" Value="Yellow"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding StatusIcon}" Value="{x:Static my:StatusIcon.Error}">
                    <Setter Property="Foreground" Value="Red}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

ถ้าใช้ ReSharper และถ้า DataContext จะตั้งขึ้นอย่างถูกต้องจะมี IntelliSense เมื่อคุณตี.หลังStatusIconคือมันจะแสดงคุณสมบัติของ enum ที่ซึ่งDebug, Info, หรือWarningError

หากใช้ ReSharper มันจะแนะนำการอัปเดตต่อไปนี้สำหรับเนมสเปซในส่วนหัวสำหรับไฟล์ XAML (มันดีแบบนั้น):

xmlns:my="clr-namespace:Class.Path.MyViewModel;assembly=MyAssembly"

และ VieModel:

public enum StatusIcon
{
    Debug,
    Info,
    Warning,
    Error
}

public class MyViewModel
{
    public StatusIcon StatusIcon { get; }
}

เรายังใช้Fodyสำหรับการผูกอัตโนมัติ


คุณกำลังอ้างถึงโครงการ Fody's PropertyChanged หรือไม่?
UuDdLrLrSs

0

คุณสามารถตั้งค่า enum เป็นค่า DataTrigger ... ทดสอบบน MSVC 2017

<TextBlock Text="Some text to be colored by an enum">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding StatusIcon}" Value="Warning">
                    <Setter Property="Foreground" Value="Yellow"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding StatusIcon}" Value="Error">
                    <Setter Property="Foreground" Value="Red}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.