![](/img/trans.png)
[英]How do I bind controls to the selected item in a listbox using WPF and the MVVM pattern?
[英]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.