簡體   English   中英

如何訪問從列表框WPF MVVM中選擇的對象的屬性

[英]How Do I Access Properties of an Object Selected from a ListBox WPF MVVM

我的ViewModel中有一個綁定到可觀察對象的列表框。 當用戶在列表框中選擇一個項目時,SelectedItem將觸發“ SelectedSandwich”屬性。 該值將保存到私有字段。 SandwichName和Description屬性是Sandwich對象的屬性。 我希望視圖中的文本塊顯示選定的三明治名稱和價格,但我不想將這些文本塊綁定到列表框元素。 這是視圖:

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

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

我嘗試將RaisePropertyChangedEvent放入三個屬性的設置器中(盡管我只需要閱讀它們),但是設置器從未執行。 實際上,從不執行SelectedSandwich屬性的設置器。 每次都會執行get。 我已遍歷代碼,但看不到問題出在哪里。 謝謝您的幫助。

也許我不清楚,但是您要在UI中設置的唯一屬性是SelectedSandwich屬性。 如果在更改所選列表框項時設置正確,那么為什么不從其他位置綁定到SelectedSandwich?

因此,如果您希望視圖中的某些文本塊顯示所選的三明治名稱和價格,請嘗試以下操作:

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

或者,如果您想使用准備好的數據模板:

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

你完成了...

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM