WPF

2016-03-31 31 views
1
'daki ana sayfa konseptini simüle ederken mantıksal hatalar

WPF Window s'deki ASP.Net ana sayfası konseptini (MVC'deki Düzen) simüle etmeye çalışıyorum. WPF

Ben Window s için bu tür bazı davranışları belirleyen bir CustomWindow sınıf var:

public class CustomWindow : Window 
{ 
    //... 
} 

Ve MasterWindowBase; Benim UserControl s çeşit alır bir CustomWindow (stil yoluyla) pencere içerik olduğu:

public abstract class MasterWindowBase : CustomWindow 
{ 
    public MasterWindowBase(MyUserControlBase content) 
    { 
     ContentUserControl = content; 
     Style = Application.Current.FindResource("MasterWindowStyle") as Style; 
    } 

    #region ContentUserControl Property 
    public MyUserControlBase ContentUserControl 
    { 
     get { return (MyUserControlBase)GetValue(ContentUserControlProperty); } 
     set { SetValue(ContentUserControlProperty, value); } 
    } 

    public static readonly DependencyProperty ContentUserControlProperty = 
     DependencyProperty.Register("ContentUserControl", typeof(MyUserControlBase), typeof(MasterWindowBase)); 
    #endregion 
} 

uygulama kaynaklarında tanımlanan stili:

 <Style x:Key="MasterWindowStyle" TargetType="{x:Type local:MasterWindowBase}"> 
      <Setter Property="Content"> 
       <Setter.Value> 
        <Grid> 
         <StackPanel> 
          <TextBlock Text="This is a master window"/> 
          <ContentPresenter Content="{Binding ContentUserControl, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MasterWindowBase}}}"/> 
         </StackPanel> 
        </Grid> 
       </Setter.Value> 
      </Setter> 
     </Style> 

Ve MasterWindow; Belirtilen UserControl tip MasterWindowBase bir örneğini oluşturmak için kullanılan genel bir pencere: İlk Window.Show Şimdi

public class MasterWindow<TMyUserControlBase> 
    : MasterWindowBase 
    where TMyUserControlBase : MyUserControlBase, new() 
{ 
    public MasterWindow() : base(new TMyUserControlBase()) { } 
} 

, her şey mükemmel çalışıyor, ama sonra iki mantıksal hatalar yakalandı:

  1. kapatayım Penceresi ve farklı bir UserControl ile yeni bir örneğini gösterir, ilk gösterilen MasterWindow içeriğini yükler.
  2. MasterWindow ile aynı UserControl numaralı yeni örneğini gösterdiğimde veya şu anda görünen pencereleri kapatmadan farklı biriyle görüntülediğimde, şu anda görüntülenen tüm MasterWindow örneklerinin içeriğini temizler ve içeriğini yükler. Yeni örnekte gösterilen ilk MasterWindow. tarzı aslında (gerçek projede) CustomWindow 'ın tarzı dayanmaktadır çünkü zaten Template özelliğini kullanan MasterWindowStyle tarzı iç Template özelliğini kullanamazsınız

Not.

Herhangi bir yardım için teşekkür ederiz.

cevap

1

Gözlemlenen davranışın nedeni, pencerenizin Stil içinde İçeriği'u ayarlamaya çalıştığınızdır. Şablon olmadığından - WPF, UserControl'ünüzle yalnızca bir kez bir ağaç oluşturacaktır. Daha sonra bu stili tekrar ve tekrar uyguladıktan sonra - aynı görsel ağaç (aynı, ilk olarak, UserControl ile) her seferinde yeniden kullanılır (ve tabi ki bir kontrol farklı ebeveynlerde kullanılamaz - bu yüzden şimdi barındırıldığı yerden kaldırılır) ve stili uyguladığınız pencereye taşındı.

Uzun lafın kısası - İçeriği WPF'de Stil ile ayarlamamalısınız. Anında sorununuzu gidermek için, İçerik yerine ContentTemplate özelliğini ayarlayabilir ve DataTemplate'de sahip olduğunuz her şeyi (her şeyi aynı bırakarak) ayarlayabilirsiniz. Bu, bunu düzeltecektir, çünkü şablonlar için her defasında yeni görsel ağaç oluşturulur.

İşte

(hala çalışmasına rağmen) ancak bir hack benzemesidir ve bunu yaparken daha iyi hükümsüz olur, henüz hala İçerik özelliğini kullanarak, bunu düzeltmek için başka bir yoludur: Burada

<Application.Resources> 
    <Grid x:Shared="False" x:Key="myControl"> 
     <StackPanel> 
      <TextBlock Text="This is a master window"/> 
      <ContentPresenter Content="{Binding ContentUserControl, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MasterWindowBase}}}"/> 
     </StackPanel> 
    </Grid> 
    <Style x:Key="MasterWindowStyle" TargetType="{x:Type local:MasterWindowBase}"> 
     <Setter Property="Content"> 
      <Setter.Value> 
       <StaticResource ResourceKey="myControl" /> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Application.Resources> 

tanımladığınız Görsel ağacınızı x ile paylaşın: Paylaşılan = "Yanlış" özniteliği. Bu öznitelik, bu kaynağa başvurulduğunda her zaman anlamına gelir - yeni örnek oluşturulur (varsayılan olarak - aynı örnek yeniden kullanılır). Sonra bu kaynağı Tarzınızın içinde referans olarak kullanıyorsunuz.

+0

Harika çözümler. Cevabınızı okuduktan sonra, aynı zamanda stile 'x: Shared = "False" özelliğini ekleyebileceğimi ve yine de 'İçerik' özelliğini kullanabileceğimi de öğrendim. Teşekkürler! –