2010-01-06 310 views
27

任何人都可以幫助以下 - 一直在玩這個,但不能爲我的生活得到它的工作。WPF綁定到Listbox selectedItem

我有一個視圖模型,其中包含以下屬性;

public ObservableCollection<Rule> Rules { get; set; } 
public Rule SelectedRule { get; set; } 

在我的XAML中,

<ListBox x:Name="lbRules" ItemsSource="{Binding Path=Rules}" 
     SelectedItem="{Binding Path=SelectedRule, Mode=TwoWay}"> 
<ListBox.ItemTemplate> 
    <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <TextBlock Text="Name:" /> 
       <TextBox x:Name="ruleName"> 
        <TextBox.Text> 
         <Binding Path="Name" UpdateSourceTrigger="PropertyChanged" /> 
        </TextBox.Text> 
       </TextBox> 
      </StackPanel> 
    </DataTemplate> 
</ListBox.ItemTemplate> 

現在的ItemsSource工作正常,我得到規則的列表,在lbRules顯示他們的名字對象。

麻煩我正在將SelectedRule屬性綁定到lbRules的SelectedItem。我嘗試將文本塊的文本屬性綁定到SelectedRule,但它始終爲空。

<TextBlock Text="{Binding Path=SelectedRule.Name}" /> 

我看到在輸出窗口中的錯誤是: BindingExpression路徑錯誤:找不到「SelectedRule」屬性。

任何人都可以幫助我這個綁定 - 我不明白爲什麼它不應該找到SelectedRule屬性。

然後我試着改變文本塊的文本屬性作爲波紋管,它工作。麻煩的是我想在我的ViewModel中使用SelectedRule。

<TextBlock Text="{Binding ElementName=lbRules, Path=SelectedItem.Name}" /> 

非常感謝您的幫助。

回答

24

首先,你需要實現INotifyPropertyChanged接口在您的視圖模型,提高在Rule setter方法的PropertyChanged事件,否則沒有結合到SelectedRule房產調控將「知道」時,已更改。

然後,您的XAML

<TextBlock Text="{Binding Path=SelectedRule.Name}" /> 

是完全有效的,如果這是TextBlockListBoxItemTemplate並且具有相同的DataContext作爲ListBox

+0

就是這樣,傻了我,我沒有在該視圖模型上實現接口。一整天早上我的頭撞在牆上! 非常感謝您的幫助。也非常感謝其他人,特別是Yacoder,花時間看看這個。 – 2010-01-06 14:27:14

+0

也謝謝我。剛剛有確切的問題。我實現了界面,但忘記提高事件。 – 2011-09-19 21:05:01

10

裏面的DataTemplate你在一個Rule的環境中工作,這就是爲什麼你不能綁定到SelectedRule.Name - 有一個Rule沒有這樣的屬性。 綁定到原始數​​據上下文(這是您的視圖模型),你可以這樣寫:

<TextBlock Text="{Binding ElementName=lbRules, Path=DataContext.SelectedRule.Name}" /> 

UPDATE:關於SelectedItem屬性綁定,它看起來完全有效的,我試過同我的機器上,它的工作原理精細。下面是我完整的測試應用程序:

XAML:

<Window x:Class="TestWpfApplication.ListBoxSelectedItem" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="ListBoxSelectedItem" Height="300" Width="300" 
    xmlns:app="clr-namespace:TestWpfApplication"> 
    <Window.DataContext> 
     <app:ListBoxSelectedItemViewModel/> 
    </Window.DataContext> 
    <ListBox ItemsSource="{Binding Path=Rules}" SelectedItem="{Binding Path=SelectedRule, Mode=TwoWay}"> 
     <ListBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <TextBlock Text="Name:" /> 
        <TextBox Text="{Binding Name}"/> 
       </StackPanel> 
      </DataTemplate> 
     </ListBox.ItemTemplate> 
    </ListBox> 
</Window> 

後面的代碼:

namespace TestWpfApplication 
{ 
    /// <summary> 
    /// Interaction logic for ListBoxSelectedItem.xaml 
    /// </summary> 
    public partial class ListBoxSelectedItem : Window 
    { 
     public ListBoxSelectedItem() 
     { 
      InitializeComponent(); 
     } 
    } 


    public class Rule 
    { 
     public string Name { get; set; } 
    } 

    public class ListBoxSelectedItemViewModel 
    { 
     public ListBoxSelectedItemViewModel() 
     { 
      Rules = new ObservableCollection<Rule>() 
      { 
       new Rule() { Name = "Rule 1"}, 
       new Rule() { Name = "Rule 2"}, 
       new Rule() { Name = "Rule 3"}, 
      }; 
     } 

     public ObservableCollection<Rule> Rules { get; private set; } 

     private Rule selectedRule; 
     public Rule SelectedRule 
     { 
      get { return selectedRule; } 
      set 
      { 
       selectedRule = value; 
      } 
     } 
    } 
} 
+0

謝謝你的回覆。 我明白你的意思,但我不確定我是否完全理解。 問題是,DataTemplate工作正常 - 我明白模板中的上下文是規則。 這是lbRules的SelectedItem與我有問題的SelectedRule屬性的綁定。 你是說通過設置ItemSource我也間接設置了列表框的DataContext? 對不起,如果我沒有說清楚。我只是使用綁定到textblock來幫助我調試問題。 – 2010-01-06 11:53:05

+0

我已經更新了我的答案。 – 2010-01-06 12:06:39

+0

非常感謝您的回覆。 您的回答對我來說非常有用,可以幫助我解決問題。事實證明,我的問題是我沒有實施InotifyPropertyChanged,這就是爲什麼我將Arconaut的答覆標記爲答案。 謝謝你的時間。有一件事確實讓我感興趣,就是爲什麼你的解決方案沒有實現INotifyPropertyChanged接口,但仍然可以工作... 無論如何,再次感謝您的時間。 – 2010-01-06 14:30:02

3

Yocoder是正確的,

DataTemplate裏面,你DataContext設置爲Rule其目前處理..

要訪問的父母DataContext,你也可以考慮使用一個RelativeSource你的綁定:

<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ____Your Parent control here___ }}, Path=DataContext.SelectedRule.Name}" /> 
RelativeSource

更多信息可以在這裏找到:

http://msdn.microsoft.com/en-us/library/system.windows.data.relativesource.aspx

-6

,因爲你設定itemsource到您的集合,您的文本框與該集合中的每個單獨項目綁定。如果您嘗試執行具有2個列表框的主 - 細節表單,則在此方案中選定的項屬性很有用。你會將第二個列表框的itemsource綁定到規則的子集合。換句話說,選定的項目提醒外部控制,你的來源已經改變,內部控制(你的數據模板中的那些已經知道這個變化)

並回答你的問題是在大多數情況下設置itemsource與設置控制的DataContext的。

+3

「設置itemsource與設置控件的datacontext相同」 - 請不要張貼廢話:) – arconaut 2010-01-06 14:12:16

0

對我來說,我通常一起使用DataContext來綁定兩個屬性,比如這個問題。

<TextBlock DataContext="{Binding SelectedRule}" Text="{Binding Name}" />

或者,我更喜歡使用ElementName,因爲它實現了綁定只與視圖控件。

<TextBlock DataContext="{Binding ElementName=lbRules, Path=SelectedItem}" Text="{Binding Name}" />

相關問題