Ich habe ein List-Feld an ein beobachtbares Objekt in meinem ViewModel gebunden. Wenn der Benutzer ein Element in der Listbox auswählt, löst das SelectedItem die Eigenschaft "SelectedSandwich" aus. Der Wert wird in einem privaten Feld gespeichert. Die Eigenschaften SandwichName und Description sind Eigenschaften des Sandwich-Objekts. Ich möchte, dass Textblöcke in meiner Ansicht ausgewählten Sandwichnamen und Preis anzeigen, aber ich möchte diese Textblöcke nicht an das Listenfeldelement binden. Hier ist die Ansicht: 'Wie greife ich auf Eigenschaften eines Objekts zu, das aus einer ListBox WPF MVVM ausgewählt wird
<Window.DataContext>
<vm:SandwichVM/>
</Window.DataContext>
<Window.Resources>
<DataTemplate x:Key="lstSandwich">
<Border BorderThickness="3"
CornerRadius="4"
HorizontalAlignment="Stretch"
BorderBrush="Blue">
<TextBlock HorizontalAlignment="Stretch">
<Run Text="{Binding SandwichName}"/>
<Run Text=" | " />
<Run Text="{Binding Description}" />
<Run Text=" | " />
<Run Text="{Binding Price}" />
</TextBlock>
</Border>
</DataTemplate>
<DataTemplate x:Key="menu" >
<Border>
<TextBlock HorizontalAlignment="Stretch">
<Run Text="{Binding SandwichName}"/>
<Run Text="{Binding Price}" />
</TextBlock>
</Border>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<ListBox Grid.Row="0" x:Name="cboMenu"
ItemsSource="{Binding Sandwiches}"
SelectedItem="{Binding SelectedSandwich, Mode=TwoWay}"
ItemTemplate="{StaticResource lstSandwich}"
Margin="3">
</ListBox>
<Grid Grid.Row="1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontStretch="ExtraExpanded"
FontFamily="Verdana"
FontSize="22"
>
<Run Text="Your Selection"/>
</TextBlock>
<Grid Grid.Row="1">
<ContentControl
ContentTemplate="{StaticResource menu}"
HorizontalAlignment="Stretch"
Margin="5,0,5,0">
</ContentControl>
</Grid>
</Grid>
</Grid>
</Window>'
Hier ist das Viewmodel:
'class SandwichVM : INotifyPropertyChanged
{
private Sandwich _selectedSandwich;
private ObservableCollection<Sandwich> _sandwiches;
public ObservableCollection<Sandwich> Sandwiches
{
get { return _sandwiches; }
}
public SandwichVM()
{
//fake data for the list
_sandwiches = new ObservableCollection<Sandwich>();
_sandwiches.Add(new Sandwich("Pastrami", "Stacked high on rye bread with a touch of mustard.", 8.50));
_sandwiches.Add(new Sandwich("Tuna", "Fresh tuna salad on wheat with slice of cheddar cheese.", 6.50));
_sandwiches.Add(new Sandwich("Steak", "Sliced grilled steak with sauteed mushrooms and onions.", 9.50));
_sandwiches.Add(new Sandwich("Chicken Salad", "Juicy chunks of chicken breast, onions, fruit.", 6.50));
_sandwiches.Add(new Sandwich("Buffalo Chicken", "Caliente! Fried chicken breast slathered with hot buffalo wing sauce.", 8.50));
_sandwiches.Add(new Sandwich("Tofu", "I don't know how to make a tofu sandwich.", 1.50));
}
public Sandwich SelectedSandwich
{
get { return _selectedSandwich; }
set
{
if (_selectedSandwich != value)
{
_selectedSandwich = value;
RaisePropertyChangedEvent("SelectedSandwich");
}
}
}
public string SandwichName
{
get { return _selectedSandwich.SandwichName; }
set
{
_selectedSandwich.SandwichName = value;
RaisePropertyChangedEvent("SandwichName");
}
}
public string Description
{
get { return _selectedSandwich.Description; }
set
{
_selectedSandwich.Description = value;
RaisePropertyChangedEvent("Description");
}
}
public string Price
{
get { return _selectedSandwich.Price.ToString(); }
set
{
_selectedSandwich.Price = Convert.ToDouble(value);
RaisePropertyChangedEvent("Price");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChangedEvent(string propertyName)
{
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}'
Ich versuchte, die RaisePropertyChangedEvent in dem Setter für die drei Eigenschaften setzen (obwohl ich sie nur lesen müssen), aber die Setter werden nie ausgeführt. Tatsächlich wird der Setter für die SelectedSandwich -Eigenschaft nie ausgeführt. Der Get wird jedes Mal ausgeführt. Ich bin durch den Code gegangen, kann aber nicht sehen, wo das Problem liegt. Vielen Dank für Ihre Hilfe.
Ihr erstes Beispiel war einer meiner Versuche. Ich bekomme nichts. Ich suche nach einer Art Tippfehler. Es gibt etwas sehr einfaches, das ich vermisse. Ihr zweites Beispiel wird nicht ausgeführt oder wird nicht kompiliert, je nachdem, was ich mache. Der Namespace ist ComboBox (ich weiß, aber ich begann mit einer Combobox). Ich habe gerade bemerkt, dass die Oberseite des Viewmodels nicht da ist. Ich habe xmlns: vm = "clr-namespace: ComboBox.ViewModel". Dann, wie Sie sehen können, habe ich den Datenkontext im Fenster festgelegt. Also verstehe ich nicht den "x: Type", den Sie vorschlagen. – ScottinTexas
Die DataTemplate ist diejenige, die Sie aufgerufen haben x: Key = "menu" und das Grid ist das, das Sie unten auf der xaml-Seite haben, fügen Sie es einfach ein. Es gibt keinen Grund, warum es nicht kompilieren sollte ... Machen Sie sich keine Sorgen mit x: Geben Sie die wichtige Think ist "SandwichVMNamespace: Sandwich" müssen Sie den Namespace Ihrer Sandwich-Klasse wie Sie zuvor, vielleicht etwas wie xmlns: sandwichVMNamespace = " clr-namespace: ComboBox.ViewModel ". Und es ist alles wegen dem tollen wpf getan ... –