ความแตกต่างระหว่าง StaticResource และ DynamicResource ใน WPF คืออะไร?


474

เมื่อใช้ทรัพยากรเช่นแปรงแม่แบบและสไตล์ใน WPF สามารถระบุได้ว่าเป็น StaticResources

<Rectangle Fill="{StaticResource MyBrush}" />

หรือเป็น DynamicResource

<ItemsControl ItemTemplate="{DynamicResource MyItemTemplate}"  />

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

  • ความแตกต่างหลักคืออะไร เช่นเดียวกับหน่วยความจำหรือความหมายของประสิทธิภาพ
  • มีกฎใน WPF เช่น "brushes มักจะคงที่" และ "template เสมอไดนามิก" ฯลฯ ?

ฉันถือว่าตัวเลือกระหว่าง Static vs Dynamic ไม่ได้เป็นตามอำเภอใจเหมือนที่ปรากฏ ... แต่ฉันไม่เห็นรูปแบบ


27
เป็นสิ่งสำคัญที่จะต้องทราบว่านักพัฒนา Windows 8 App ไม่มี DyanmicResource เป็นตัวเลือกเพียง StaticResource
Jerry Nixon

2
@Jerry Nixon ขอบคุณพระเจ้าสำหรับสิ่งนั้นฉันนับจำนวนครั้งที่ฉันไม่สามารถทำงานอะไรได้เพราะฉันใช้ DynamicResource แทน StaticResource หรือในทางกลับกัน จากมุมมองของโปรแกรมเมอร์นี่เป็นความซับซ้อนที่ไม่จำเป็น การเปรียบเทียบคือคำจำกัดความของตัวแปรฉันต้องระบุอย่างชัดเจนว่ามันอาศัยอยู่บนฮีปหรือสแต็กหรือไม่? และถ้าฉันเข้าใจผิดมันจะพ่นข้อผิดพลาด runtime ที่ร้ายแรง
Contango

สำหรับคำอธิบายอย่างละเอียดมากขึ้นของ StaticResource และ DynamicResource และเมื่อใช้แต่ละดูmsdn.microsoft.com/en-us/library/ms750613%28v=vs.100%29.aspx
Michael Repucci

คำตอบ:


466

StaticResourceจะได้รับการแก้ไขและมอบหมายให้สถานที่ให้บริการระหว่างการโหลดของ XAML ซึ่งเกิดขึ้นก่อนที่จะประยุกต์จะทำงานจริง จะได้รับมอบหมายเพียงครั้งเดียวและการเปลี่ยนแปลงใด ๆ ในพจนานุกรมทรัพยากรจะถูกละเว้น

DynamicResourceกำหนดวัตถุ Expression สถานที่ให้บริการระหว่างการโหลด แต่ไม่จริงค้นหาทรัพยากรจนรันไทม์เมื่อวัตถุ Expression จะถามหาค่า สิ่งนี้ทำให้มองหารีซอร์สจนกว่าจำเป็นต้องรันไทม์ ตัวอย่างที่ดีคือการอ้างอิงไปข้างหน้าไปยังทรัพยากรที่กำหนดในภายหลังใน XAML อีกตัวอย่างหนึ่งคือทรัพยากรที่ไม่มีอยู่จริงจนกระทั่งรันไทม์ มันจะอัพเดทเป้าหมายหากมีการเปลี่ยนแปลงพจนานุกรมทรัพยากรต้นฉบับ


4
สิ่งที่ต้องเปลี่ยนก่อนที่ฉันจะต้องใช้ DynamicResource ยกตัวอย่างเทมเพลต: ฉันกำหนดหนึ่งครั้ง แต่แน่นอนว่าทริกเกอร์และสิ่งต่าง ๆ สามารถเปลี่ยนเนื้อหาของเทมเพลตได้ แต่เทมเพลตยังคงเหมือนเดิม StaticResource ทำที่นี่หรือไม่
Isak Savo

5
ใช้ StaticResource หากทรัพยากรที่คุณแนบนั้นถูกกำหนดไว้ใน XAML ก่อนจุดใช้งานและจะไม่เปลี่ยนแปลงตลอดอายุการใช้งานของแอปพลิเคชันที่กำลังทำงาน ในกรณีนี้คุณจะได้รับประสิทธิภาพที่ดีขึ้นด้วย StaticResource
Phil Wright

4
คือการผูกสองทางจะใช้กับทั้งสองสิ่งนี้ถ้าใช่สิ่งที่จะแตกต่างกันในกรณีนั้น?
WhoIsNinja

11
ประโยคสุดท้ายมีความสำคัญจริง ๆ :It will update the target if the source resource dictionary is changed.
MEMark

4
@IsakSavo พิจารณา UI ด้วยชุดรูปแบบสีด้วยทรัพยากรแบบไดนามิกคุณสามารถสลับหนึ่งพจนานุกรมสำหรับอีกพจนานุกรมหนึ่งและทรัพยากรอ้างอิงใด ๆ ในพจนานุกรมใหม่จะอัปเดตโดยอัตโนมัติ
Gusdor

119

ฉันยังสับสนเกี่ยวกับพวกเขา ดูตัวอย่างด้านล่าง:

<Window x:Class="WpfApplicationWPF.CommandsWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="CommandsWindow" Height="300" Width="300">

    <StackPanel>
        <Button Name="ButtonNew" 
                Click="ButtonNew_Click" 
                Background="{DynamicResource PinkBrush}">NEW</Button>
        <Image Name="ImageNew" 
               Source="pack://application:,,,/images/winter.jpg"></Image>
    </StackPanel>


    <Window.Background>
        <DynamicResource ResourceKey="PinkBrush"></DynamicResource>
    </Window.Background>

</Window>

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

หากฉันเพิ่มรหัสด้านล่างเพื่อคลิกเหตุการณ์ของปุ่มเนื่องจากพวกเขาใช้ DynamicResource พื้นหลังจะได้รับการอัปเดตตามลำดับ

private void ButtonNew_Click(object sender, RoutedEventArgs e)
{
    this.Resources.Add(  "PinkBrush"
                         ,new SolidColorBrush(SystemColors.DesktopColor)
                       );
}

หากพวกเขาใช้ StaticResource:

  • ต้องประกาศทรัพยากรใน XAML
  • และนั่นก็เป็นคำว่า "ก่อน" ด้วยเช่นกัน

หวังว่าฉันจะสับสนบางอย่าง


31

StaticResource จะได้รับการแก้ไขในการสร้างวัตถุ
DynamicResource จะถูกประเมินและแก้ไขทุกครั้งที่การควบคุมต้องการทรัพยากร


21
  1. StaticResource ใช้ค่าแรก DynamicResource ใช้ล่าสุดค่า
  2. DynamicResource สามารถใช้สำหรับการกำหนดสไตล์ซ้อนกันได้ StaticResource ไม่สามารถทำได้

สมมติว่าคุณมีพจนานุกรมสไตล์ซ้อนกัน LightGreen อยู่ในระดับรากขณะที่ Pink ซ้อนกันอยู่ใน Grid

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Style TargetType="{x:Type Grid}">
        <Style.Resources>
            <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
                <Setter Property="Background" Value="Pink"/>
            </Style>
        </Style.Resources>
    </Style>
    <Style TargetType="{x:Type Button}" x:Key="ConflictButton">
        <Setter Property="Background" Value="LightGreen"/>
    </Style>
</ResourceDictionary>

ในมุมมอง:

<Window x:Class="WpfStyleDemo.ConflictingStyleWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="ConflictingStyleWindow" Height="100" Width="100">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Styles/ConflictingStyle.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <Button Style="{DynamicResource ConflictButton}" Content="Test"/>
    </Grid>
</Window>

StaticResource จะแสดงปุ่มเป็น LightGreen ซึ่งเป็นค่าแรกที่พบในสไตล์ DynamicResource จะแทนที่ปุ่ม LightGreen เป็น Pink ในขณะที่มันแสดงผล Grid

StaticResource StaticResource

DynamicResource DynamicResource

โปรดทราบว่า VS Designer ปฏิบัติต่อ DynamicResource เป็น StaticResource มันจะได้รับค่าแรก ในกรณีนี้ VS Designer จะแสดงปุ่มเป็น LightGreen แม้ว่าจริง ๆ แล้วจะกลายเป็นสีชมพู

StaticResource จะโยนข้อผิดพลาดเมื่อลบสไตล์ระดับราก (LightGreen) ออก


13

ความแตกต่างหลักคืออะไร เช่นเดียวกับหน่วยความจำหรือความหมายของประสิทธิภาพ

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

ทรัพยากรคงที่ดึงมาหนึ่งครั้งโดยอ้างอิงองค์ประกอบและใช้สำหรับอายุการใช้งานของทรัพยากร ในขณะที่ DynamicResources จะดึงข้อมูลทุกครั้งที่มีการใช้งาน

ข้อเสียของทรัพยากรแบบไดนามิกคือพวกเขามักจะลดประสิทธิภาพของแอปพลิเคชัน

มีกฎใน WPF เช่น "brushes มักจะคงที่" และ "template เสมอไดนามิก" ฯลฯ ?

แนวทางปฏิบัติที่ดีที่สุดคือการใช้ทรัพยากรแบบคงที่เว้นแต่ว่ามีเหตุผลเฉพาะเช่นคุณต้องการเปลี่ยนทรัพยากรในรหัสที่อยู่เบื้องหลังแบบไดนามิก อีกตัวอย่างของอินสแตนซ์ที่คุณต้องการให้ t ใช้ resoruces แบบไดนามิกรวมเมื่อคุณใช้ SystemBrushes, SystenFonts และพารามิเตอร์ระบบ


7

พบคำตอบทั้งหมดที่มีประโยชน์เพียงแค่ต้องการเพิ่มกรณีการใช้งานอีกหนึ่งกรณี

ในสถานการณ์จำลอง WPF การควบคุมผู้ใช้ของคุณสามารถใช้ทรัพยากรที่กำหนดไว้ในหน้าต่างหลัก / การควบคุมอื่น ๆ (ที่กำลังจะเป็นโฮสต์การควบคุมผู้ใช้นี้) โดยอ้างอิงถึงทรัพยากรนั้นเป็น DynamicResource

ตามที่ผู้อื่นกล่าวถึง Staticresource จะค้นหาในเวลารวบรวม การควบคุมผู้ใช้ไม่สามารถอ้างถึงทรัพยากรที่กำหนดไว้ในการควบคุมโฮสต์ / ผู้ปกครอง แม้ว่า DynamicResource สามารถใช้ในกรณีนี้


3

ประโยชน์ที่สำคัญของทรัพยากรแบบไดนามิก

หากการเริ่มต้นแอปพลิเคชันใช้เวลานานมากคุณจะต้องใช้ทรัพยากรแบบไดนามิกเนื่องจากทรัพยากรแบบสแตติกจะถูกโหลดเสมอเมื่อสร้างหน้าต่างหรือแอปในขณะที่โหลดทรัพยากรแบบไดนามิกเมื่อมีการใช้งานครั้งแรก

อย่างไรก็ตามคุณจะไม่เห็นประโยชน์ใด ๆ ยกเว้นว่าทรัพยากรของคุณมีขนาดใหญ่และซับซ้อนมาก


สำหรับ DynamicResources เป็นการสร้างปัญหาด้านประสิทธิภาพเพียงครั้งเดียว (ใช้ครั้งแรก) หรือเป็นทุกครั้งที่มีการใช้องค์ประกอบ
Morgane

ในกรณีนี้เขตข้อมูลที่ใช้มากที่สุดจะต้องเป็นทรัพยากรแบบคงที่เขตข้อมูลที่ใช้กำหนดเองสามารถเป็นแบบไดนามิกเช่นสำหรับทรัพยากรหลักหน้าต่างแบบคงที่และทรัพยากรหน้าต่างโต้ตอบสามารถเป็นแบบไดนามิก
zamoldar

2

ทรัพยากรแบบไดนามิกสามารถใช้ได้เมื่อตั้งค่าคุณสมบัติเป็นวัตถุซึ่งมาจากวัตถุอ้างอิงหรือ freezable โดยที่ทรัพยากรแบบคงที่สามารถใช้ที่ใดก็ได้ คุณสามารถแยกการควบคุมทั้งหมดออกได้โดยใช้ทรัพยากรคงที่

ทรัพยากรแบบคงที่จะใช้ภายใต้สถานการณ์ต่อไปนี้:

  1. เมื่อไม่จำเป็นต้องเปลี่ยนทรัพยากรปฏิกิริยาที่รันไทม์
  2. หากคุณต้องการประสิทธิภาพที่ดีพร้อมทรัพยากรมากมาย
  3. ในขณะที่อ้างอิงทรัพยากรภายในพจนานุกรมเดียวกัน

ทรัพยากรแบบไดนามิก:

  1. ค่าของคุณสมบัติหรือชุดรูปแบบลักษณะไม่รู้จักจนกระทั่งรันไทม์
    • ซึ่งรวมถึงระบบการใช้งานการตั้งค่าตามธีม
    • รวมถึงการอ้างอิงล่วงหน้า
  2. การอ้างอิงทรัพยากรขนาดใหญ่ที่อาจไม่โหลดเมื่อเพจ, windows, usercontrol โหลด
  3. การอ้างอิงสไตล์ของธีมในคอนโทรลแบบกำหนดเอง
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.