2016-06-20 37 views
0

我有一個列表框綁定到我的ViewModel中的可觀察對象。當用戶在列表框中選擇一個項目時,SelectedItem會觸發「SelectedSandwich」屬性。該值將保存到專用字段。屬性SandwichName和Description是三明治對象的屬性。我想在我的視圖中的文本塊顯示選定的三明治名稱和價格,但我不想將這些文本塊綁定到列表框元素。 這裏是視圖: '如何訪問從列表框中選擇的對象的屬性WPF MVVM

<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>' 

這裏是視圖模型:

'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)); 
    }' 

我試圖把RaisePropertyChangedEvent在setter方法三個屬性(雖然我只需要讀取它們),但制定者從不執行。實際上,SelectedSandwich屬性的setter永遠不會執行。 get每次都執行。我已經瀏覽了代碼,但看不清問題所在。 謝謝你的幫助。

回答

0

也許它對我不明確,但是您從UI設置的唯一屬性是SelectedSandwich屬性。如果在更改所選列表框項目時設置正確,那麼爲什麼不綁定到其他地方的SelectedSandwich?

所以,如果你想在你看來一些文本塊,顯示選擇sandwichname和價格只是嘗試這樣的:

<TextBlock Text="{Binding SelectedSandwich.Name}"/> 
<TextBlock Text="{Binding SelectedSandwich.Price}"/> 

或者,如果你想用你準備的DataTemplate:

<DataTemplate DataType="{x:Type sandwichVMNamespace:Sandwich}"> 
    <Border> 
     <TextBlock HorizontalAlignment="Stretch"> 
      <Run Text="{Binding SandwichName}"/> 
      <Run Text="{Binding Price}" /> 
     </TextBlock> 
    </Border> 
</DataTemplate> 

<Grid Grid.Row="1"> 
    <ContentControl 
     Content="{Binding SelectedSandwich}" 
     HorizontalAlignment="Stretch" 
     Margin="5,0,5,0"> 
    </ContentControl> 
</Grid> 

而且你完成了...

+0

你的第一個例子是我的一個試驗。我什麼都沒得到。我一直在尋找某種錯字。有一件事很簡單,我錯過了。你的第二個例子不會運行或不會編譯,這取決於我做了什麼。命名空間是組合框(我知道,但我從一個組合框開始)。我只注意到viewmodel的頂部不在那裏。我有xmlns:vm =「clr-namespace:ComboBox.ViewModel」。然後,你可以看到我在窗口上設置了數據上下文。所以我不明白你提出的「x:Type」。 – ScottinTexas

+0

DataTemplate是您稱爲x:Key =「menu」的一個,並且網格是您在xaml頁面底部的網格,只需粘貼即可。沒有理由爲什麼它不應該編譯...不要打擾與x:鍵入重要的想法是「sandwichVMNamespace:三明治」,你必須指定你的三明治類的命名空間,就像你以前做的,也許像xmlns:sandwichVMNamespace =「 CLR命名空間:ComboBox.ViewModel」。而這一切都是因爲偉大的WPF而完成的...... –