2012-09-26 4 views
0

Silverlight의 캔버스에있는 모든 이미지와 텍스트 "레이어"를 표시하는 목록 상자가 필요합니다. 목록 상자를 보려고하거나 요소를 추가 할 때 목록 상자를 볼 때 현재 코드가 충돌합니다. 나는 이유를 알 수 없다. 누군가가 이것으로 올바른 방향으로 나를 가리킬 수 있습니까?Silverlight에서 프로그래밍 방식으로 목록 상자에 바인딩하기

XML - 당신이 당신의 Grid 요소에 경로 속성을 사용하여 바인딩 때문에

      <Grid DataContext="{Binding Path=Project}"> 
           ... 
           ... 
           <TextBlock Name="textBlock1" Text="Layers" Margin="18,16,0,0" /> 

           <StackPanel Grid.Row="1" Grid.RowSpan="2" Grid.ColumnSpan="2"> 
            <ListBox ItemsSource="{Binding Path=Elements}" Height="175" Name="listBox1" Width="172"/> 
           </StackPanel> 

          </Grid> 

Project.cs는

 //List of elements 
    private ObservableCollection<FrameworkElement> elements; 
    public ObservableCollection<FrameworkElement> Elements 
    { 
     get { return elements; } 
     set 
     { 
      elements = value; 
      NotifyPropertyChanged("Elements"); 
     } 
    } 
// An example of how an element is added to the Elements collection 
// There are also image elements added similarly 
private void AddTextElement(object param) 
    { 
     TextBlock textBlock = new TextBlock(); 
     textBlock.Text = "New Text"; 
     textBlock.Foreground = new SolidColorBrush(Colors.Gray); 
     textBlock.FontSize = 25; 
     textBlock.FontFamily = new FontFamily("Arial"); 
     textBlock.Cursor = Cursors.Hand; 
     textBlock.Tag = null; 


     this.Elements.Add(textBlock); 
     numberOfElements++; 


     this.SelectedElement = textBlock; 
     this.selectedTextElement = textBlock; 
    } 

private void AddImageElement(object param) 
    { 
     bool? gotImage; 
     string fileName; 
     BitmapImage imageSource = GetImageFromLocalMachine(out gotImage, out fileName); 


     if (gotImage == true) 
     { 
      Image image = new Image(); 
      OrderElements(image); 
      image.Name = fileName; 
      image.Source = imageSource; 
      image.Height = imageSource.PixelHeight; 
      image.Width = imageSource.PixelWidth; 
      image.MaxHeight = imageSource.PixelHeight; 
      image.MaxWidth = imageSource.PixelWidth; 
      image.Cursor = Cursors.Hand; 
      image.Tag = null; 


      AddDraggingBehavior(image); 
      image.MouseLeftButtonUp += element_MouseLeftButtonUp; 

      this.Elements.Add(image); 
      numberOfElements++; 

      this.SelectedElement = image; 
      this.SelectedImageElement = image; 

     } 
    } 

답변

1

이유 중 하나는, 수 있습니다.

바인딩 원본을 사용해야하며 바인딩 원본을 호출 할 때 지정할 수있는 정적 리소스로 Project 개체를 설정해야합니다. 이처럼

: 당신이 객체를 가리 때 "소스"를 사용하고, "경로"당신이 속성을 가리 :

<Window 
    xlmns:local="NamespaceOfMyProject"> 

    <Window.Resources> 
     <local:Project x:key="MyProjectResource" /> 
    </Window.Resources> 

    <Grid DataContext="{Binding Source={StaticResource MyProjectResource}}> 
    .... 
    </Grid> 
    .... 
</Window> 

이유입니다.

DataContext를 설정하는 또 다른 방법은이 코드를 사용하여 코드 숨김에서 수행하는 것입니다. 하지만 먼저 그리드의 이름을 지정, 그래서는 코드 숨김에서 참조 할 수 있습니다

<Grid x:Name="myGrid"> 

Codebehind가 : 일반적으로 충돌의 원인이됩니다 잘못 이미지 작업

myGrid.DataContext = new Project(); 
0

; 요소 구현 및 이미지 설정 방법을 보여주는 코드를 보여줍니다.

또한 XAML에 ItemTemplate이 없습니다. 여기서, u는 이미지와 텍스트를 설정합니다.

0

Canvas에 추가 한 FrameworkElements가 있기 때문에 충돌이 나는 것 같지만 목록에 추가 할 수도 있습니다. FrameworkElements는 일반적으로 시각적 트리에 여러 번 추가되는 것을 싫어합니다.

이 문제의 경우,이 같은 일이 (ElementsAsStrings에 목록을 바인딩) 그것을 해결 있습니다 이것은 그럴듯한 소리

private ObservableCollection<FrameworkElement> elements; 
    public ObservableCollection<FrameworkElement> Elements 
    { 
     get { return elements; } 
     set 
     { 
      if(elements != null) 
       elements.CollectionChanged -= onElementsChanged; 
      elements = value; 
      if(elements != null) 
       elements.CollectionChanged += onElementsChanged; 

      NotifyPropertyChanged("Elements"); 
      NotifyPropertyChanged("ElementsAsStrings"); 
     } 
    } 

    public IEnumerable<string> ElementsAsStrings 
    { 
     get 
     { 
      foreach(var element in Elements) 
      { 
       if(element is TextBox) 
        yield return (element as TextBox).Text; 
       // More cases here 
      } 
     } 
    } 

    private void onElementsChanged(object sender, NotifyCollectionChangedEventArgs e) 
    { 
     NotifyPropertyChanged("ElementsAsStrings"); 
    } 
+0

. 이 문제를 해결하기 위해 어쨌든 알고 있습니까? 텍스트 요소의 일부 텍스트를 표시하지만 이미지의 파일 이름 만 표시하려고합니다. – Steve

+0

나는 이것을 어떻게 수행했는지 보여주기 위해 위의 대답을 업데이트했다. –

관련 문제