Olay işleme için WPF'de bir kaynak sözlüğünün arkasında kod ayarlamak mümkün müdür?


148

WPF'de bir kaynak sözlüğünün arkasında kod ayarlamak mümkün mü? Örneğin, bir düğme için bir kullanıcı denetiminde, onu XAML'de bildirirsiniz. Düğme tıklaması için olay işleme kodu, kontrolün arkasındaki kod dosyasında yapılır. Bir düğmeyle bir veri şablonu oluşturacak olsaydım, kaynak sözlüğündeki düğme tıklaması için olay işleyici kodunu nasıl yazabilirim.


1
Bunu yapmanın doğru yolu bir komut kullanmaktır, ayrıca size düğmeyi etkinleştirme ve devre dışı bırakma yeteneği verirken, bazı yanıtların bana bir hack gibi koktuğunu önerdiği şekilde yapabilirsiniz.
Aran Mulholland

Yanıtlar:


209

Sanırım sorduğun şey, ResourceDictionary için arka plan kod dosyası istiyorsun. Bunu kesinlikle yapabilirsiniz! Aslında, bunu bir Pencere ile aynı şekilde yaparsınız:

MyResourceDictionary adlı bir ResourceDictionary'niz olduğunu varsayalım. MyResourceDictionary.xaml dosyanızda, x: Class özniteliğini kök öğeye şu şekilde yerleştirin:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    x:Class="MyCompany.MyProject.MyResourceDictionary"
                    x:ClassModifier="public">

Ardından, aşağıdaki bildirimle MyResourceDictionary.xaml.cs adlı dosyanın arkasında bir kod oluşturun:

namespace MyCompany.MyProject
{
    partial class MyResourceDictionary : ResourceDictionary
    { 
       public MyResourceDictionary()
       {
          InitializeComponent();
       }     
       ... // event handlers ahead..
    }
}

Ve bitirdiniz. Kodun arkasına dilediğinizi koyabilirsiniz: yöntemler, özellikler ve olay işleyicileri.

== Windows 10 uygulamaları için güncelleme ==

Ve UWP ile oynuyorsanız, dikkat etmeniz gereken bir şey daha var:

<Application x:Class="SampleProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:rd="using:MyCompany.MyProject">
<!-- no need in x:ClassModifier="public" in the header above -->

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>

                <!-- This will NOT work -->
                <!-- <ResourceDictionary Source="/MyResourceDictionary.xaml" />-->

                <!-- Create instance of your custom dictionary instead of the above source reference -->
                <rd:MyResourceDictionary />

            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

</Application>

7
Ageektrapped'ın cevabına bir ek olarak: Codebehind sınıfınızın tam nitelikli adını x: Class niteliğine koyduğunuzdan emin olun. x:Class="MyCompany.MyProject.MySubFolder1.MyResourceDictionary"Aksi takdirde, yalnızca x: Class = "MyResourceDictionary" koyarsanız, xaml ayrıştırıcısı sınıfınızı bulamaz.
viggity

29
Kısmi sınıf kodunda varsayılan bir kurucu sağladığınızdan ve InitializeComponent () öğesini çağırdığından emin olun. (Benim durumumda, kaynak sözlüğünü dışa aktarmak için MEF kullanıyordum.)
Scott Whitlock

4
Yükseltilen yorum için güncellenmiş kod pasajı. Cevabı tamamlamam gerektiğini hissettim; yaygın bir hata. Şimdi yaptım :) Beğenmediyseniz geri dönün. Cevap için teşekkürler.
Gishu

2
Bunun (en azından wp8.1'de) artık geçerli olmadığını ve kaynak sözlüğünüzün referansları için özel bir kullanıcı denetimi oluşturmanız gerektiğini unutmayın
Jared

10
Ayrıca, ResourceDictionary'nin XAML dosyasındaki Derleme Eylemini "Sayfa" olarak ayarlamanız gerekir, aksi takdirde InitializeComponent () çağrısı derlenmez. (ResourceDictionary XAML dosyaları genellikle varsayılan olarak "Resource" olarak ayarlanır.)
user1454265

9

"Ageektrapped" e katılmıyorum ... Kısmi sınıf yöntemini kullanmak iyi bir uygulama değildir. Sözlüğü sayfadan ayırmanın amacı ne olur?

Bir arka plan kodundan, şunu kullanarak ax: Name öğesine erişebilirsiniz:

Button myButton = this.GetTemplateChild("ButtonName") as Button;
if(myButton != null){
   ...
}

Sen yapabilirsin bu size kontrolleri yaparken özel denetim yükleri için Kargaburun istiyorsanız OnApplyTemplate yöntemde. Bunu yapmak için OnApplyTemplate'in geçersiz kılınması gerekiyor. Bu yaygın bir uygulamadır ve tarzınızın kontrolden kopuk kalmasını sağlar. (Tarz, kontrole bağlı olmamalıdır, ancak kontrol, bir stile sahip olmaya bağlı olmalıdır).


8
Phobis Bence Sözlüğü sayfadan ayırmanın amacı, Ana Sayfa xaml'ın yeniden kullanılabilirliği ve okunabilirliği ile ilgili. Yukarıdaki çözüm benim için de çalıştı.
cleftheris

5

Gishu - bu "genellikle teşvik edilmeyen bir uygulama" gibi görünse de, işte bunu yapmak isteyebileceğiniz bir neden:

Metin kutularının odaklandıklarında standart davranışı, düzeltme işaretinin, kontrol odağı kaybettiğinde olduğu konuma yerleştirilmesidir. Uygulamanızın tamamında, kullanıcı herhangi bir metin kutusuna sekmelerde metin kutusunun tüm içeriğinin vurgulandığını tercih ederseniz, kaynak sözlüğüne basit bir işleyici eklemek işinizi görecektir.

Varsayılan kullanıcı etkileşim davranışının kullanıma hazır davranıştan farklı olmasını istediğiniz herhangi bir başka neden, bir kaynak sözlüğünde bir kod için iyi adaylar gibi görünüyor.

Uygulama işlevselliğine özgü herhangi bir şeyin bir kaynak sözlüğünün arkasındaki kodda olmaması gerektiğini tamamen kabul edin.


0

XAML, kod içermeyen nesne grafikleri oluşturmak içindir.
Bir Veri şablonu, özel bir kullanıcı nesnesinin ekranda nasıl işleneceğini belirtmek için kullanılır ... (örneğin, bu bir liste kutusu öğesi ise) davranışı, bir veri şablonunun uzmanlık alanının bir parçası değildir. Çözümü yeniden çizin ...


Sonuç: Kaynak dic'in arkasında kod varken kullanılmasını tavsiye eder misiniz? Hiç kullanmadım, şüpheliyim.
Shimmy Weitzhandler

1
Yapmam - bana doğru gelmiyor. Sözlük, belirli anahtarlar için değerler döndürmelidir. OP'nin durumunda, kodu veri şablonuyla birlikte paketlemek .. Farklı bir yaklaşım denemeyi tercih ederim .. Örneğin Komut modelini kullanın. Bir diff çözümü önermek için OP'nin sorunu hakkında daha fazla ayrıntıya ihtiyacım var.
Gishu

1
Kesinlikle katılmıyorum. MVVM ile, arkasında koda sahip olmanın son derece yararlı olduğu bir senaryo vardır: ekli özelliklerin geliştirilmesi. Arkasındaki kodla çalışmasını sağlayın, ardından ekli bir mülke taşıyın. Manhattan büyüklüğünde bir beyniniz yoksa, bu ekli mülkü sıfırdan geliştirmekten çok daha hızlıdır.
Contango
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.