2015-07-15 2 views
1

Я новый пчела в WPF, я пытаюсь заполнить свой контроль COMBOX, который есть в моем ListBoxBind выпадающий в ListBox WPF

XAML:

 <Window.Resources> 
    <DataTemplate x:Key="UserTemplate" > 
     <StackPanel Orientation="Horizontal" > 
     <ComboBox Name="rule" ItemsSource="{Binding}" DisplayMemberPath="DataContext.RuleType" Width="85" Height="20" 
      SelectedValuePath="DataContext.RuleType" SelectedValue="{Binding Path=DataContext.RuleType}"/> 
     <TextBlock Text="{Binding Path= Name1}" Width="85" Margin="5,5,5,5"></TextBlock> 
     <Button Content="Delete" Click="cmdDeleteUser_Clicked" Margin="5,5,5,5" /> 
     <Button Content="Add" Click="cmdAddUser_Clicked" Margin="5,5,5,5" /> 
     </StackPanel> 
    </DataTemplate> 

    </Window.Resources> 

    <Grid> 
    <ListBox Name="lbUsers" ItemsSource="{Binding }" ItemTemplate="{StaticResource UserTemplate}"/> 
    </Grid> 

КОД ЗА:

 public ObservableCollection<User> Users; 
     ObservableCollection<Listdata> listeddata; 
     ObservableCollection<Records> Record; 


     public MainWindow() 
     { 
      InitializeComponent(); 
      Users = new ObservableCollection<User>() { 
        new User() { Name = "", Age = "" }, 
       }; 

      DataboundListbox.Records record = new Records(); 
      RuleType = record.record_Rule(); 
      lbUsers.DataContext = Users; 

     } 
     private string _Name; 
     public string Name1 
     { 
      get { return _Name; } 
      set 
      { 
       if (value != _Name) 
       { 
        _Name = "John"; 
        NotifyPropertyChanged("Name"); 
       } 
      } 
     } 
     private List<string> _RuleType; 
     public List<string> RuleType 
     { 
      get { return _RuleType; } 
      set 
      { 
       if (value != _RuleType) 
       { 
        _RuleType = value; 
        NotifyPropertyChanged("RuleType"); 
       } 
      } 
     } 

     private void NotifyPropertyChanged(string info) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
      } 
     } 

     private void cmdDeleteUser_Clicked(object sender, RoutedEventArgs e) 
     { 
      Button cmd = (Button)sender; 
      if (cmd.DataContext is User) 
      { 
       User deleteme = (User)cmd.DataContext; 
       Users.Remove(deleteme); 
      } 
     } 
     private void cmdAddUser_Clicked(object sender, RoutedEventArgs e) 
     { 
      Button cmd = (Button)sender; 
      if (cmd.DataContext is User) 
      { 
       var addedUser = new User() { Name = "", Age = "" }; 
      Users.Add(addedUser); 
      } 
     } 


     private List<string> _prp; 
     public List<string> prp 
     { 
      get { return _prp; } 
      set 
      { 
       if (value != _prp) 
       { 
        _RuleType = value; 
        NotifyPropertyChanged("prp"); 
       } 
      } 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 
+0

Я тоже новичок в XAML, специально переплета материал, но я нашел, что это руководство довольно легко и просто. Возможно, вы можете проверить свой код против него. https://msdn.microsoft.com/en-us/library/windows/apps/xaml/hh464965.aspx – Veverke

+0

Каков ожидаемый элемент ItemSource для вашего ListView и Combobox? Кажется, что ваша привязка неверна. – Joseph

+0

Вы должны использовать ObservableCollection вместо списков. –

ответ

0

Прежде чем я могу ответить на ваш вопрос, есть некоторые неясности, которые должны быть устранены.

  1. Если User уже член имени Name то что Name1 в родительском классе?

  2. Если RuleType является список, как же он установлен как SelectedValue вашего ComboBox, не должна быть ComboBox.itemsSource вместо этого? Если это так, то где свойство, указанное для сохранения ComboBox.SelectedValue?

  3. Как появилась кнопка Add внутри UserTemplate? Delete кнопка в порядке, но я думаю, Add принадлежит за пределами ListBox.

Если я правильно понимаю вашу проблему, то это решение, о котором я могу думать.

Fisrt: User нужна недвижимость как SelectedRule держать Combobox.SelectedItem:

public class User : INotifyPropertyChanged 
{ 

    // implementation of INotifyPropertyChanged 

    string _name; 
    public string Name 
    { 
     get 
     { 
      return _name; 
     } 
     set 
     { 
      _name = value; 
      NotifyPropertyChanged("Name"); 
     } 
    } 

    int _age; 
    public int Age 
    { 
     get 
     { 
      return _age; 
     } 
     set 
     { 
      _age = value; 
      NotifyPropertyChanged("Age"); 
     } 
    } 

    string _selectedRule; 
    public string SelectedRule 
    { 
     get 
     { 
      return _selectedRule; 
     } 
     set 
     { 
      _selectedRule = value; 
      NotifyPropertyChanged("SelectedRule"); 
     } 
    } 
} 

Второго: Ваш DataTemplate должен измениться, как это:

<Window.Resources> 
    <DataTemplate x:Key="UserTemplate" > 
     <StackPanel Orientation="Horizontal" > 
      <ComboBox Name="rule" ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=RuleType}" DisplayMemberPath="." Width="85" Height="20" 
     SelectedItem="{Binding SelectedRule}"/> 
      <TextBlock Text="{Binding Path= Name}" Width="85" Margin="5,5,5,5"></TextBlock> 
      <Button Content="Delete" Click="cmdDeleteUser_Clicked" Margin="5,5,5,5" /> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

И наконец изменений ListBox части как b Elow:

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*"/> 
     <RowDefinition Height="Auto"/> 
    </Grid.RowDefinitions> 
    <ListBox Grid.Row="0" Name="lbUsers" ItemsSource="{Binding}" ItemTemplate="{StaticResource UserTemplate}"/> 
    <Button Grid.Row="1" Content="Add" Click="cmdAddUser_Clicked" Margin="5,5,5,5" /> 
</Grid> 

Если вы собираетесь принести Add кнопку вне как приведенный выше код, то вы должны удалить if (cmd.DataContext is User) из cmdAddUser_Clicked метода.

+0

Hi bahman_aries, спасибо за исправления, которые это очень помогло. 1.name1 было другим свойством, которое я создал при исправлении ошибки, поэтому он только что получил копию, вставленную 2. Я установил datacontext в codebehind, остальная часть кода xaml была пробной и ошибкой, поэтому, вставляя ее, я dint удалил его .. мой плохой кнопки 3.Add и Delete должны быть там в шаблоне данных. Еще раз спасибо !!! – Nyk

+0

Добро пожаловать. –

1

Проблема:

Основная проблема на этом две линии:

{Binding Path=DataContext.RuleType} 
    {Binding Path= Name1} 
  1. Так как вы уже объявить DataContext, DataContext.RuleType будет вызывает компилятор для поиска yourdatacontext.DataContext.RuleType который явно не то, что вы хотите.

    lbUsers.DataContext = Users; 
    
  2. Ваш контекст данных представляет собой набор класса User и не содержит Name1. Таким образом Binding Path = Name1 будет возвращать "свойство не найден"

Решение

В WPF MVVM (вид модели ViewModel) модель настоятельно рекомендуется. Одной из его основных особенностей является отдельная логика GUI от Business Logic, что делает код более чистым и удобным в обслуживании.

Шаг 1: Создание ViewModel

public class UserViewModel:INotifyPropertyChanged 
{ 
    private string name; 
    private string age; 
    private string rule; 
    private List<string> ruleType; 

    public String Name 
    { 
     get { return name; } 
     set { name = value; NotifyPropertyChanged("Name"); } 
    } 

    public String Age 
    { 
     get { return age; } 
     set { age = value; NotifyPropertyChanged("Age"); } 
    } 

    public String Rule 
    { 
     get { return rule; } 
     set { rule = value; NotifyPropertyChanged("Rule"); } 
    } 
    public List<string> RuleType 
    { 
     get { return ruleType; } 
     set { ruleType = value; NotifyPropertyChanged("RuleType"); } 
    } 

    public UserViewModel() 
    { 
     name = "name"; 
     age = ""; 
     ruleType = new List<string>(); 
    } 

    #region NotifyPropertyChanged 
    public event PropertyChangedEventHandler PropertyChanged; 
    protected void NotifyPropertyChanged(String info) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 
    #endregion 
} 

} 

Шаг 2: Свяжите контекст данных в ViewModel

public MainWindow() 
    { 
     InitializeComponent(); 
     Users = new ObservableCollection<UserViewModel>(); 
     //setup your data here 
     //example: 

     UserViewModel userViewModel = new UserViewModel(); 
     //populate your combobox here 
     userViewModel.RuleType.Add("rule1") 
     userViewModel.RuleType.Add("rule2"); 
     userViewModel.RuleType.Add("rule3"); 
     Users.Add(new UserViewModel()); 

     lbUsers.DataContext = Users ; 

    } 

Шаг 3: Обновите XAML

<Window.Resources> 
     <DataTemplate x:Key="UserTemplate" > 
      <StackPanel Orientation="Horizontal" > 
       <ComboBox Name="rule" ItemsSource="{Binding RuleType}" Width="85" Height="20" 
     SelectedValue="{Binding Rule}"/> 
       <TextBlock Text="{Binding Path= Name}" Width="85" Margin="5,5,5,5"></TextBlock> 
       <Button Content="Delete" Click="cmdDeleteUser_Clicked" Margin="5,5,5,5" /> 
       <Button Content="Add" Click="cmdAddUser_Clicked" Margin="5,5,5,5" /> 
      </StackPanel> 
     </DataTemplate> 

    </Window.Resources> 

Когда я набрав, бахман уже опубликовал довольно подробный ответ. Поэтому я остановился здесь. Если вам потребуются какие-либо объяснения или решения от меня, я просто попрошу.

В будущем, если вы подозреваете какую-либо ошибку в отношении привязки, вы можете выполнить поиск в своем окне вывода. Если вы видите свое выходное окно, которое вы, возможно, будет найден этот

System.Windows.Data Error: 40 : BindingExpression path error: 'DataContext' property not found on 'object' ''User' (HashCode=9080996)'. BindingExpression:Path=DataContext.RuleType; DataItem='User' (HashCode=9080996); target element is 'ComboBox' (Name=''); target property is 'SelectedValue' (type 'Object') 
System.Windows.Data Error: 40 : BindingExpression path error: 'Name1' property not found on 'object' ''User' (HashCode=9080996)'. BindingExpression:Path=Name1; DataItem='User' (HashCode=9080996); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String') 
+0

Nice MVVM пояснение (+1). –

Смежные вопросы