我有一个列表框绑定到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放在三个属性的setter中(虽然我只需要读取它们)但是setter永远不会被执行。实际上,从不执行SelectedSandwich属性的setter。每次执行get。我已经完成了代码,但无法查看问题所在。 谢谢你的帮助。
答案 0 :(得分:0)
也许我不清楚,但是你从UI设置的唯一属性是SelectedSandwich属性。如果在更改所选列表框项时它设置正确,那么为什么不从其他位置绑定到SelectedSandwich?
因此,如果您希望视图中的某些文本块显示选定的三明治名称和价格,请尝试以下内容:
<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>
你完成了......