Zrobiłem przykładowy demo VS 2010 RC przykładowy projekt, ponieważ w moim projekcie produkcyjnym mam ten sam błąd przy użyciu MVVM.ContentTemplateSelector jest wywoływany tylko jeden raz pokazując zawsze ten sam datatemplate
W moim projekcie próbki demo używam tylko kodu źródłowego bez 3rd zależności partii, dzięki czemu można pobrać projekt demo tutaj i uruchomić go dla siebie: http://www.sendspace.com/file/mwx7wv
Teraz do problemu: Kiedy klikam dziewczęta/chłopcy przycisk powinien przełączać datatemplate, nie?
Co mam nie tak?
OK Oferuję tutaj fragment kodu zbyt:
Code-Behind MainWindow.cs:
namespace ContentTemplateSelectorDemo
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Person person;
public MainWindow()
{
InitializeComponent();
person = new Person(){ Gender = "xxx"};
person.IsBoy = true;
ContentGrid.DataContext = person;
}
private void btnBoys_Click(object sender, RoutedEventArgs e)
{
person.IsBoy = true;
person.IsGirl = false;
this.ContentGrid.DataContext = person;
}
private void btnGirls_Click(object sender, RoutedEventArgs e)
{
person.IsGirl = true;
person.IsBoy = false;
this.ContentGrid.DataContext = person;
}
}
}
XAML MainWindow.xaml: Klasa
<Window x:Class="ContentTemplateSelectorDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ContentTemplateSelectorDemo"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="girlsViewTemplate">
<local:UserControl1 />
</DataTemplate>
<DataTemplate x:Key="boysViewTemplate" >
<local:UserControl2 />
</DataTemplate>
<local:PersonDataTemplateSelector x:Key="PersonSelector" />
</Window.Resources>
<Grid x:Name="ContentGrid" >
<StackPanel>
<Button Name="btnGirls" Click="btnGirls_Click">Switch Girls</Button>
<Button Name="btnBoys" Click="btnBoys_Click">Switch Boys</Button>
<ContentControl Content="{Binding}" ContentTemplateSelector="{StaticResource ResourceKey=PersonSelector}" />
</StackPanel>
</Grid>
</Window>
DataTemplateSelector :
public class PersonDataTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item,DependencyObject container)
{
if (item is Person)
{
Person person = item as Person;
Window window = Application.Current.MainWindow;
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(window))
return null;
if (person.IsBoy)
return window.FindResource("boysViewTemplate") as DataTemplate;
if (person.IsGirl)
return window.FindResource("girlsViewTemplate") as DataTemplate;
}
return null;
}
}
:)
Lepsze fragmenty kodu pocztowego zamiast oferując pobrania , ludzie najprawdopodobniej nie będą pobierać tha t. –
ok edytowałem mój wpis init! – msfanboy
ok po niektórych badań: http://joshsmithonwpf.wordpress.com/2007/03/18/updating-the-ui-when-binding-directly-to-business-objects-that-are-modified/ tak jak Josh powiedział w swoim komentarzu do kodu: "... Jest to konieczne, ponieważ system wiążący WPF zignoruje powiadomienie PropertyChanged, jeśli właściwość zwróci tę samą referencję obiektu, co wcześniej ..." Nie mogę zwróć ten sam obiekt, zamiast tego muszę odtworzyć obiekt Person w module obsługi zdarzeń przycisków, takim jak: ... = new Person() {IsBoy = true, IsGirl = false} etc ... to działa. dziękuję josh! – msfanboy