การทำให้แอปพลิเคชัน WPF ดูเป็นสไตล์เมโทรแม้แต่ใน Windows 7? (หน้าต่าง Chrome / ธีม / ธีม)


123

ฉันชอบหน้าต่าง Chrome บน Office Suite และ Visual Studio ใหม่:

ใส่คำอธิบายภาพที่นี่

ฉันยังคงพัฒนาแอปพลิเคชันสำหรับ Windows 7 แต่ฉันสงสัยว่ามีวิธีที่ง่ายและรวดเร็ว (อ่าน: สไตล์ WPF หรือ Windows Library) เพื่อเลียนแบบสไตล์นี้ ฉันเคยทำสไตล์โครเมี่ยมหน้าต่างมาแล้ว แต่การทำให้มันดูและประพฤติถูกต้องเป็นเรื่องยุ่งยากมาก

มีใครทราบบ้างว่ามีเทมเพลตหรือไลบรารีเพื่อเพิ่มรูปลักษณ์ "UI สมัยใหม่" ให้กับแอปพลิเคชัน WPF ของฉันหรือไม่


8
แพ็คเกจ Guide / NuGet นี้อาจเป็นประโยชน์: MahaApps Metroประกอบด้วยชุดรูปแบบและการควบคุมเพื่อสร้างแอป WPF ด้วยรูปลักษณ์และความรู้สึกของ Metro
Oliver Vogel

คำถามที่ขอให้เราแนะนำหรือค้นหาหนังสือเครื่องมือห้องสมุดซอฟต์แวร์บทช่วยสอนหรือทรัพยากรนอกสถานที่อื่น ๆนั้นไม่เกี่ยวข้องกับ Stack Overflow เนื่องจากมีแนวโน้มที่จะดึงดูดคำตอบที่แสดงความคิดเห็นและสแปม ให้อธิบายปัญหาและสิ่งที่ได้ดำเนินการไปแล้วเพื่อแก้ไข
Scott Solmer

คำตอบ:


149

สิ่งที่ฉันทำคือการสร้างหน้าต่างและสไตล์ของตัวเอง เพราะฉันชอบที่จะควบคุมทุกอย่างและฉันไม่ต้องการให้ไลบรารีภายนอกบางส่วนใช้หน้าต่างจากมัน ฉันดูMahApps Metro ที่กล่าวถึงแล้วบน GitHub

MahApps

และยังดีมากModern UI บน GitHub (.NET4.5 เท่านั้น)

UI ที่ทันสมัย

มีอีกหนึ่งอย่างคือElysiumแต่ฉันไม่ได้ลองอันนี้จริงๆ

สวรรค์

สไตล์ที่ฉันทำนั้นง่ายมากเมื่อฉันดูว่ามันเป็นอย่างไรในสิ่งเหล่านี้ ตอนนี้ฉันมีหน้าต่างของตัวเองและฉันสามารถทำอะไรก็ได้ที่ต้องการด้วย xaml ... สำหรับฉันมันเป็นเหตุผลหลักว่าทำไมฉันถึงทำของตัวเอง และฉันก็ทำเพิ่มให้คุณอีกเช่นกัน :) ฉันน่าจะบอกว่าฉันคงทำไม่ได้ถ้าไม่สำรวจUI สมัยใหม่มันช่วยได้มาก ฉันพยายามทำให้ดูเหมือน VS2012 Window หน้าตาเป็นแบบนี้

MyWindow

นี่คือรหัส (โปรดทราบว่ามีการกำหนดเป้าหมาย. NET4.5)

public class MyWindow : Window
{

    public MyWindow()
    {
        this.CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, this.OnCloseWindow));
        this.CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, this.OnMaximizeWindow, this.OnCanResizeWindow));
        this.CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, this.OnMinimizeWindow, this.OnCanMinimizeWindow));
        this.CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, this.OnRestoreWindow, this.OnCanResizeWindow));
    }

    private void OnCanResizeWindow(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = this.ResizeMode == ResizeMode.CanResize || this.ResizeMode == ResizeMode.CanResizeWithGrip;
    }

    private void OnCanMinimizeWindow(object sender, CanExecuteRoutedEventArgs e)
    {
        e.CanExecute = this.ResizeMode != ResizeMode.NoResize;
    }

    private void OnCloseWindow(object target, ExecutedRoutedEventArgs e)
    {
        SystemCommands.CloseWindow(this);
    }

    private void OnMaximizeWindow(object target, ExecutedRoutedEventArgs e)
    {
        SystemCommands.MaximizeWindow(this);
    }

    private void OnMinimizeWindow(object target, ExecutedRoutedEventArgs e)
    {
        SystemCommands.MinimizeWindow(this);
    }

    private void OnRestoreWindow(object target, ExecutedRoutedEventArgs e)
    {
        SystemCommands.RestoreWindow(this);
    }
}

และที่นี่แหล่งข้อมูล:

<BooleanToVisibilityConverter x:Key="bool2VisibilityConverter" />

<Color x:Key="WindowBackgroundColor">#FF2D2D30</Color>
<Color x:Key="HighlightColor">#FF3F3F41</Color>
<Color x:Key="BlueColor">#FF007ACC</Color>
<Color x:Key="ForegroundColor">#FFF4F4F5</Color>

<SolidColorBrush x:Key="WindowBackgroundColorBrush" Color="{StaticResource WindowBackgroundColor}"/>
<SolidColorBrush x:Key="HighlightColorBrush" Color="{StaticResource HighlightColor}"/>
<SolidColorBrush x:Key="BlueColorBrush" Color="{StaticResource BlueColor}"/>
<SolidColorBrush x:Key="ForegroundColorBrush" Color="{StaticResource ForegroundColor}"/>

<Style x:Key="WindowButtonStyle" TargetType="{x:Type Button}">
    <Setter Property="Foreground" Value="{DynamicResource ForegroundColorBrush}" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="VerticalContentAlignment" Value="Center" />
    <Setter Property="Padding" Value="1" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
                <Grid Background="{TemplateBinding Background}">
                    <ContentPresenter x:Name="contentPresenter"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                          SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                          Margin="{TemplateBinding Padding}"
                          RecognizesAccessKey="True" />
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsMouseOver" Value="True">
                        <Setter Property="Background" Value="{StaticResource HighlightColorBrush}" />
                    </Trigger>
                    <Trigger Property="IsPressed" Value="True">
                        <Setter Property="Background" Value="{DynamicResource BlueColorBrush}" />
                    </Trigger>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter TargetName="contentPresenter" Property="Opacity" Value=".5" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

<Style x:Key="MyWindowStyle" TargetType="local:MyWindow">
    <Setter Property="Foreground" Value="{DynamicResource ForegroundColorBrush}" />
    <Setter Property="Background" Value="{DynamicResource WindowBackgroundBrush}"/>
    <Setter Property="ResizeMode" Value="CanResizeWithGrip" />
    <Setter Property="UseLayoutRounding" Value="True" />
    <Setter Property="TextOptions.TextFormattingMode" Value="Display" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyWindow">
                <Border x:Name="WindowBorder" Margin="{Binding Source={x:Static SystemParameters.WindowNonClientFrameThickness}}" Background="{StaticResource WindowBackgroundColorBrush}">
                    <Grid>
                        <Border BorderThickness="1">
                            <AdornerDecorator>
                                <Grid x:Name="LayoutRoot">
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="25" />
                                        <RowDefinition Height="*" />
                                        <RowDefinition Height="15" />
                                    </Grid.RowDefinitions>
                                    <ContentPresenter Grid.Row="1" Grid.RowSpan="2" Margin="7"/>
                                    <Rectangle x:Name="HeaderBackground" Height="25" Fill="{DynamicResource WindowBackgroundColorBrush}" VerticalAlignment="Top" Grid.Row="0"/>
                                    <StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" WindowChrome.IsHitTestVisibleInChrome="True" Grid.Row="0">
                                        <Button Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}" ToolTip="minimize" Style="{StaticResource WindowButtonStyle}">
                                            <Button.Content>
                                                <Grid Width="30" Height="25" RenderTransform="1,0,0,1,0,1">
                                                    <Path Data="M0,6 L8,6 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center"
                                                        Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2"  />
                                                </Grid>
                                            </Button.Content>
                                        </Button>
                                        <Grid Margin="1,0,1,0">
                                            <Button x:Name="Restore" Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}" ToolTip="restore" Visibility="Collapsed" Style="{StaticResource WindowButtonStyle}">
                                                <Button.Content>
                                                    <Grid Width="30" Height="25" UseLayoutRounding="True" RenderTransform="1,0,0,1,.5,.5">
                                                        <Path Data="M2,0 L8,0 L8,6 M0,3 L6,3 M0,2 L6,2 L6,8 L0,8 Z" Width="8" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"
                                                            Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1"  />
                                                    </Grid>
                                                </Button.Content>
                                            </Button>
                                            <Button x:Name="Maximize" Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}" ToolTip="maximize" Style="{StaticResource WindowButtonStyle}">
                                                <Button.Content>
                                                    <Grid Width="31" Height="25">
                                                        <Path Data="M0,1 L9,1 L9,8 L0,8 Z" Width="9" Height="8" VerticalAlignment="Center" HorizontalAlignment="Center"
                                                            Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="2"  />
                                                    </Grid>
                                                </Button.Content>
                                            </Button>
                                        </Grid>
                                        <Button Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}" ToolTip="close"  Style="{StaticResource WindowButtonStyle}">
                                            <Button.Content>
                                                <Grid Width="30" Height="25" RenderTransform="1,0,0,1,0,1">
                                                    <Path Data="M0,0 L8,7 M8,0 L0,7 Z" Width="8" Height="7" VerticalAlignment="Center" HorizontalAlignment="Center"
                                                        Stroke="{Binding Foreground, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Button}}" StrokeThickness="1.5"  />
                                                </Grid>
                                            </Button.Content>
                                        </Button>
                                    </StackPanel>
                                    <TextBlock x:Name="WindowTitleTextBlock" Grid.Row="0" Text="{TemplateBinding Title}" HorizontalAlignment="Left" TextTrimming="CharacterEllipsis" VerticalAlignment="Center"  Margin="8 -1 0 0"  FontSize="16"  Foreground="{TemplateBinding Foreground}"/>
                                    <Grid Grid.Row="2">
                                        <Path x:Name="ResizeGrip" Visibility="Collapsed" Width="12" Height="12" Margin="1" HorizontalAlignment="Right"
                                        Stroke="{StaticResource BlueColorBrush}" StrokeThickness="1" Stretch="None" Data="F1 M1,10 L3,10 M5,10 L7,10 M9,10 L11,10 M2,9 L2,11 M6,9 L6,11 M10,9 L10,11 M5,6 L7,6 M9,6 L11,6 M6,5 L6,7 M10,5 L10,7 M9,2 L11,2 M10,1 L10,3" />
                                    </Grid>
                                </Grid>
                            </AdornerDecorator>
                        </Border>
                        <Border BorderBrush="{StaticResource BlueColorBrush}" BorderThickness="1" Visibility="{Binding IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Converter={StaticResource bool2VisibilityConverter}}" />
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="WindowState" Value="Maximized">
                        <Setter TargetName="Maximize" Property="Visibility" Value="Collapsed" />
                        <Setter TargetName="Restore" Property="Visibility" Value="Visible" />
                        <Setter TargetName="LayoutRoot" Property="Margin" Value="7" />
                    </Trigger>
                    <Trigger Property="WindowState" Value="Normal">
                        <Setter TargetName="Maximize" Property="Visibility" Value="Visible" />
                        <Setter TargetName="Restore" Property="Visibility" Value="Collapsed" />
                    </Trigger>
                    <MultiTrigger>
                        <MultiTrigger.Conditions>
                            <Condition Property="ResizeMode" Value="CanResizeWithGrip" />
                            <Condition Property="WindowState" Value="Normal" />
                        </MultiTrigger.Conditions>
                        <Setter TargetName="ResizeGrip" Property="Visibility" Value="Visible" />
                    </MultiTrigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="WindowChrome.WindowChrome">
        <Setter.Value>
            <WindowChrome CornerRadius="0" GlassFrameThickness="1" UseAeroCaptionButtons="False" />
        </Setter.Value>
    </Setter>
</Style>

1
สวัสดีและขอบคุณมากสำหรับรหัสที่ดีที่คุณโพสต์ เป็นไปได้ไหมที่จะมีเงาบนหน้าต่าง? สิ่งเดียวที่ฉันคิดว่าจะมีการเปลี่ยนแปลงไปGlassFrameThickness 1แต่เงานั้นแข็งแกร่งและมืดเกินไป ฉันจะเปลี่ยนน้ำหนักและความทึบได้อย่างไร?
xperator


การสร้างการปรับแต่งส่วนประกอบของตัวเองเป็นเรื่องยากมากหรือไม่แทนที่จะใช้ MahApps
Matheus Saraiva

Fantastico! ขอบคุณมากสำหรับผลงานที่ยอดเยี่ยมนี้ฉันพยายามทำสิ่งเดียวกันหลายครั้ง แต่ไม่เคยได้ผลลัพธ์ที่สมบูรณ์แบบ
Leodev

สมมติว่าฉันต้องการเพิ่มความหนาของขอบสีน้ำเงินด้านบนและลบเส้นขอบด้านอื่น ๆ ทั้งหมด (เช่นรูป elysium ในคำตอบของคุณ) ฉันต้องเปลี่ยนอะไร ฉันใหม่เพื่อ WPF และด้วยเหตุนี้คำถาม
mrid

49

วิธีการแก้ปัญหาที่ผมจบลงด้วยการเลือกเป็นMahApps.Metro ( GitHub ) ซึ่ง (หลังจากที่ใช้มันสองชิ้นส่วนของซอฟแวร์ในขณะนี้) ผมคิดว่าชุด UI ที่ดีเยี่ยม(เครดิตให้กับโอลิเวอร์ Vogelสำหรับคำแนะนำ)

สไตล์หน้าต่าง

สกินแอปพลิเคชันโดยใช้ความพยายามเพียงเล็กน้อยและมีการปรับเปลี่ยนการควบคุมมาตรฐานของ Windows 8 มันแข็งแกร่งมาก

ลายน้ำกล่องข้อความ

มีเวอร์ชันใน Nuget:

คุณสามารถติดตั้ง MahApps.Metro ผ่าน Nuget โดยใช้ GUI (คลิกขวาที่โปรเจ็กต์ของคุณจัดการ Nuget References ค้นหา 'MahApps.Metro') หรือผ่านคอนโซล:

PM> ติดตั้งแพ็กเกจ MahAppsMetro

นอกจากนี้ยังฟรีแม้ใช้ในเชิงพาณิชย์

ปรับปรุง 10-29-2556:

ฉันค้นพบว่า MahAppsMetro เวอร์ชัน Github เต็มไปด้วยการควบคุมและรูปแบบที่ไม่มีในเวอร์ชันปัจจุบันรวมถึง:

datagrids:

ใส่คำอธิบายภาพที่นี่

ทำความสะอาดหน้าต่าง:

ใส่คำอธิบายภาพที่นี่

Flyouts:

ใส่คำอธิบายภาพที่นี่

กระเบื้อง:

ใส่คำอธิบายภาพที่นี่

ที่เก็บ github มีการใช้งานมากโดยมีการสนับสนุนของผู้ใช้ค่อนข้างน้อย ฉันขอแนะนำให้ลองดู


ฉันทดสอบมันดี +1 :)
Akrem

3
อัพเดทดีมาก! ฉันลองใช้ MahApps ด้วยเช่นกัน Metro, Modern UI สำหรับ WPF และ Elysium ฉันพบว่า Elysium นั้นซับซ้อนมากในการใช้งานและสร้างความสับสนบนเว็บไซต์ / Doc ของพวกเขา UI สมัยใหม่และ MahApps Metro มีน้ำหนักเบาและใช้งานง่าย แต่ MahApps เมโทรแข่งขันได้มากขึ้นในการควบคุมฟอร์ม WPF
Cheung

การสร้างการปรับแต่งส่วนประกอบของตัวเองเป็นเรื่องยากมากหรือไม่แทนที่จะใช้ MahApps
Matheus Saraiva

42

ฉันจะแนะนำModern UI สำหรับ WPF

มีผู้ดูแลที่กระตือรือร้นมากและฟรี!

Modern UI สำหรับ WPF (ภาพหน้าจอของแอปพลิเคชันตัวอย่าง

ฉันกำลังย้ายโปรเจ็กต์บางอย่างไปยัง MUI ความประทับใจแรก (และในขณะที่สอง) คือว้าว

หากต้องการดูการทำงานของ MUI คุณสามารถดาวน์โหลดXAML Spyซึ่งใช้ MUI ได้

แก้ไข:ใช้ Modern UI สำหรับ WPF ไม่กี่เดือนและฉันรักมัน!


16

จากคำตอบของ Viktor La Croixพร้อมแหล่งที่มาด้านบนฉันจะเปลี่ยนเป็นใช้สิ่งต่อไปนี้:

ตัวอย่างแบบอักษร Marlett

เป็นแนวทางปฏิบัติที่ดีกว่าในการใช้แบบอักษร Marlett แทนที่จะเป็นจุดข้อมูลเส้นทางสำหรับปุ่มย่อเล็กสุดกู้คืน / ขยายใหญ่สุดและปิด

<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Top" WindowChrome.IsHitTestVisibleInChrome="True" Grid.Row="0">
<Button Command="{Binding Source={x:Static SystemCommands.MinimizeWindowCommand}}" ToolTip="minimize" Style="{StaticResource WindowButtonStyle}">
    <Button.Content>
        <Grid Width="30" Height="25">
            <TextBlock Text="0" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="3.5,0,0,3" />
        </Grid>
    </Button.Content>
</Button>
<Grid Margin="1,0,1,0">
    <Button x:Name="Restore" Command="{Binding Source={x:Static SystemCommands.RestoreWindowCommand}}" ToolTip="restore" Visibility="Collapsed" Style="{StaticResource WindowButtonStyle}">
        <Button.Content>
            <Grid Width="30" Height="25" UseLayoutRounding="True">
                <TextBlock Text="2" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="2,0,0,1" />
            </Grid>
        </Button.Content>
    </Button>
    <Button x:Name="Maximize" Command="{Binding Source={x:Static SystemCommands.MaximizeWindowCommand}}" ToolTip="maximize" Style="{StaticResource WindowButtonStyle}">
        <Button.Content>
            <Grid Width="31" Height="25">
                <TextBlock Text="1" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="2,0,0,1" />
            </Grid>
        </Button.Content>
    </Button>
</Grid>
<Button Command="{Binding Source={x:Static SystemCommands.CloseWindowCommand}}" ToolTip="close"  Style="{StaticResource WindowButtonStyle}">
    <Button.Content>
        <Grid Width="30" Height="25">
            <TextBlock Text="r" FontFamily="Marlett" FontSize="14" VerticalAlignment="Center" HorizontalAlignment="Center" Padding="0,0,0,1" />
        </Grid>
    </Button.Content>
</Button>


สวัสดี Flying maverick คุณพอจะอธิบายได้หรือไม่ว่าเหตุใดจึงควรใช้แบบอักษร marlett ฉันมีการใช้งานที่แตกต่างกันสามแบบและฉันไม่แน่ใจว่าจะใช้อันไหนดี ประการแรกคือการใช้จุดข้อมูลเส้นทางที่สองใช้ marlett และครั้งที่สามเป็นการใช้ปุ่มในรูปแบบ SVG ฉันพยายามใช้แนวทางปฏิบัติที่ดีที่สุด 100% ในโครงการนี้และไม่แน่ใจว่าข้อใดเป็นตัวเลือกที่ดีที่สุด คุณช่วยอธิบายได้ไหมว่าทำไม Marlett ถึงดีกว่า?
user1632018

1
สวัสดี user1632018 หากคุณต้องการสร้างหน้าต่างโครเมี่ยมแบบกำหนดเองใน Winform หรือ WPF คุณควรดูแบบอักษร "Marlett" ที่มีอยู่ในระบบของคุณ ฟอนต์นี้มีร่ายมนตร์จริงที่ใช้ใน Windows สำหรับปุ่มย่อเล็กสุดขยายใหญ่สุดคืนค่าและปิด การใช้แบบอักษรนี้ทำให้ง่ายต่อการนำร่ายมนตร์เหล่านี้กลับมาใช้ใหม่ในหน้าต่างโครเมี่ยมที่กำหนดเองแทนที่จะใช้รูปภาพแบบกำหนดเองที่มักใช้ คุณสามารถดูแบบอักษร Marlett ใน Windows Character Map หรือลิงก์ต่อไปนี้สำหรับรายละเอียดเพิ่มเติม: microsoft.com/typography/fonts/font.aspx?FMID=1264 หวังว่านี่จะช่วยได้
FlyingMaverick

2

หากคุณมีความเต็มใจที่จะจ่ายผมขอแนะนำให้คุณส่วนประกอบ Telerik สำหรับ WPF พวกเขานำเสนอสไตล์ / ธีมที่ยอดเยี่ยมและมีธีมเฉพาะสำหรับทั้ง Office 2013 และ Windows 8 (แก้ไข: และสไตล์ธีม Visual Studio 2013) อย่างไรก็ตามมีมากกว่าเพียงแค่รูปแบบในความเป็นจริงคุณจะได้รับการควบคุมมากมายที่มีประโยชน์จริงๆ

นี่คือลักษณะการทำงาน (ภาพหน้าจอที่นำมาจากตัวอย่าง Telerik):

ตัวอย่าง Telerik Dashboard

ตัวอย่างแดชบอร์ด Telerik CRM

นี่คือลิงก์ไปยังตัวอย่างแดชบอร์ดผู้บริหารของ telerik (ภาพหน้าจอแรก) และที่นี่สำหรับหน้าแดชบอร์ด CRM (ภาพหน้าจอที่สอง)

พวกเขาให้ทดลองใช้ 30 วันเพียงแค่ลองยิง!


0

ลองดูที่นี้หน้าต่าง WPF รถไฟใต้ดินสไตล์ที่มีเส้นขอบเรืองแสงตัวเลือก

นี่เป็นแอปพลิเคชันแบบสแตนด์อโลนที่ไม่มีไลบรารีอื่นนอกจาก Microsoft Windows.Shell (รวมอยู่ด้วย) เพื่อสร้างหน้าต่างสไตล์เมโทรพร้อมเส้นขอบเรืองแสงที่เป็นทางเลือก

รองรับ Windows ไปจนถึง XP (.NET4)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.