2013-04-02 2 views
0

내 문제 : 나는 개 소유자와 함께 목록 상자가 있으며 개가있는 목록 상자가 있습니다. 나는 개는 다음과 같은 ItemTemplate을을 목록 상자 수정할 : 국지적 인 처음 두가 성공적으로 DogName (TextBlock의) + DogKind (TextBlock의) + 소유자 (콤보),하지만 난 콤보 상자에 기존 소유자를 추가 기운 다. 내 콤보 상자에 다음과 같이 이름을 지정하면 :목록에서 콤보 박스에 요소 추가

<ComboBox x:Name="mycombo" /> 

나는 C# 코드에서 mycombo 변수를 볼 수 없습니다. XAML :

<Window x:Class="CodeFirst.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:sajat="clr-namespace:CodeFirst" 
     Title="MainWindow" Height="557.638" Width="721.294" 
     > 
<Grid x:Name="grid1"> 
<ListBox x:Name="listbox2" HorizontalAlignment="Left" Height="313" Margin="338,10,0,0" VerticalAlignment="Top" Width="250"> 
      <ListBox.ItemTemplate> 
       <DataTemplate> 
        <StackPanel Orientation="Horizontal">       
         <TextBlock Text="{Binding Path=Name}"/> 
         <TextBlock Text=", "/> 
         <TextBlock Text="{Binding Path=Kind}"/>  
         <ComboBox /> 
        </StackPanel> 
       </DataTemplate> 
      </ListBox.ItemTemplate> 
</ListBox>  
</Grid> 
</Window> 

어떻게 콤보 상자에 itemsource을 줄 수있는, 또는 내가 어떻게 소유자를 추가 도달 할 수있다?

+0

3 개의 텍스트 상자를 사용하지 말고 1을 사용하고 형식이 지정된 문자열로 텍스트 블록의 텍스트를 변경하거나 변환기를 사용하십시오. – David

답변

0

당신의 DataContext를 사용하는 경우에는 다음과 같이 바인딩 설정할 수 있습니다, 모두의

<ComboBox ItemsSource="{Binding Path=DataContext.MyItemsSource, UpdateSourceTrigger=PropertyChanged, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"></ComboBox> 
0

먼저 WPF 또는 다른 XAML 기반 기술과 함께 작동하려면를 이해해야합니다 그

UI is not Data. Data is Data. UI is UI.

이것은 당신이 데이터를 채울하기 위해, 코드의 모든 ComboBox 또는 다른 UI 요소를 조작하지만, 대신 ViewModel를 생성하고 이러한 객체를 바인드되지 않게해야 함을 의미한다. 이 예에서

Window이 간단한 예제이기 때문에 그 자체가 ViewModel로 사용되지만 별도의 클래스에 모든 응용 프로그램 논리를 이동 고려해야합니다

<Window x:Class="MiscSamples.UIisNotData" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="UIisNotData" Height="300" Width="300"> 
    <UniformGrid Rows="1" Columns="2"> 
     <DockPanel> 
      <TextBlock Text="Owners:" DockPanel.Dock="Top" FontWeight="Bold" TextAlignment="Center" Margin="2"/> 
      <Button Content="Add" Width="80" DockPanel.Dock="Bottom" Margin="2" Click="AddOwner"/> 

      <ListBox ItemsSource="{Binding Owners}"> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <Grid> 
          <TextBlock Text="{Binding Name}" x:Name="block"/> 
          <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Visibility="Collapsed" x:Name="box"/> 
         </Grid> 
         <DataTemplate.Triggers> 
          <DataTrigger Binding="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType=ListBoxItem}}" Value="True"> 
           <Setter TargetName="block" Property="Visibility" Value="Collapsed"/> 
           <Setter TargetName="box" Property="Visibility" Value="Visible"/> 
          </DataTrigger> 
         </DataTemplate.Triggers> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 
     </DockPanel> 

     <DockPanel> 
      <TextBlock Text="Dogs:" DockPanel.Dock="Top" FontWeight="Bold" TextAlignment="Center" Margin="2"/> 
      <ListBox ItemsSource="{Binding Dogs}" HorizontalContentAlignment="Stretch"> 
       <ListBox.ItemTemplate> 
        <DataTemplate> 
         <DockPanel> 
          <ComboBox ItemsSource="{Binding DataContext.Owners, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" 
             SelectedItem="{Binding Owner}" DisplayMemberPath="Name" 
             DockPanel.Dock="Right" Width="100"/> 
          <TextBlock> 
           <Run Text="{Binding Name}"/> 
           <Run Text=", "/> 
           <Run Text="{Binding Kind}"/> 
          </TextBlock> 
         </DockPanel> 
        </DataTemplate> 
       </ListBox.ItemTemplate> 
      </ListBox> 
     </DockPanel> 
    </UniformGrid> 
</Window> 

코드 뒤에 (이 코드는 배치해야)는 뷰 모델에 :

public partial class UIisNotData : Window 
    { 
     public ObservableCollection<Owner> Owners { get; set; } 
     public ObservableCollection<string> Kinds { get; set; } 
     public ObservableCollection<Dog> Dogs { get; set; } 

     public UIisNotData() 
     { 
      InitializeComponent(); 

      Owners = new ObservableCollection<Owner> 
       { 
        new Owner() {Name = "Jack"}, 
        new Owner() {Name = "Mike"}, 
        new Owner() {Name = "Kirk"}, 
        new Owner() {Name = "John"}, 
       }; 

      Kinds = new ObservableCollection<string> 
       { 
        "Affenpinscher", 
        "Afghan Hound", 
        "Airedale Terrier", 
        "Akita" 
        //.. All the rest of dog Breeds taken from http://www.petmd.com/dog/breeds?breed_list=az#.UVsQKpPcmQo 
       }; 

      Dogs = new ObservableCollection<Dog> 
       { 
        new Dog() {Name = "Bobby", Kind = Kinds[0], Owner = Owners[0]}, 
        new Dog() {Name = "Fido", Kind = Kinds[1], Owner = Owners[1]}, 
        new Dog() {Name = "Toby", Kind = Kinds[2], Owner = Owners[2]} 
       }; 

      DataContext = this; 
     } 

     private void AddOwner(object sender, RoutedEventArgs e) 
     { 
      Owners.Add(new Owner(){Name = "New Owner"}); 
     } 
    } 

데이터 모델 :

,489,332 10 개

PropertyChangedBase 클래스 :

public class PropertyChangedBase:INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged(string propertyName) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

결과 :

enter image description here

이 예제에 대해 고려할 필요가 3 개 중요한 측면이 있습니다

  • 내가에서 오전은 UI를 조작하는 방법은 없다. ents in code. 그것은 WPF에서 대부분의 시간을 완전히 불필요합니다.
  • WPF에서 양방향 바인딩을 지원하기 위해 데이터 모델의 클래스는 INotifyPropertyChanged을 구현합니다.
  • 컬렉션은 요소 (자동 ListBoxes 등을 업데이트하기 위해) 추가/컬렉션으로부터 제거되는 경우 자동 통지를 지원하기 위해 입력 ObservableCollection<T>의이다.

내 예제의 XAML 요소에 특정 크기 또는 Margin 값이 없다는 것을 알 수 있습니다.Margin="338,10,0,0"과 같은 것들은 일반적으로 Visual Studio 디자이너에서 가져온 것으로, 제대로 구조화되지 않은 레이아웃을 나타냅니다. WPF (DockPanel, StackPanel, Grid, UniformGrid, WrapPanel 등)의 Layout 요소를 살펴보고 디자이너를 사용하는 대신 XAML을 직접 코딩하는 것이 좋습니다. 이렇게하면 훨씬 높은 수준의 확장 성이 가능하며 고정 위치 요소의 뉘앙스를 줄일 수 있습니다.

관련 문제