1

我想在画布上显示多个图像。我需要在画布中以不同的方式定位它们。我为我的图像做了一个类:

class MapItem:Image
{
  public int DistanceToTop { get; set; }
  public int DistanceToLeft { get; set; }
}

我的 XAML 看起来像这样:

<UserControl.DataContext>
    <Map:MapViewModel/>
</UserControl.DataContext>

<ItemsControl ItemsSource="{Binding All}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemContainerStyle>
        <Style TargetType="Image">
            <Setter Property="Canvas.Left" Value="{Binding DistanceToLeft}" />
            <Setter Property="Canvas.Top" Value="{Binding DistanceToTop}" />
        </Style>
    </ItemsControl.ItemContainerStyle>
</ItemsControl>

我的 ViewModel 用作 DataContext :

class MapViewModel : ViewModelBase
{
  public ObservableCollection<MapItem> All   { get; set; }

  public MapViewModel()
  {
    All = new ObservableCollection<MapItem>();
    var wSource = new BitmapImage(new Uri(@"ImagePath"));
    var wImage = new MapItem { Source = wSource, DistanceToLeft = 20, DistanceToTop = 20 };
    test = wImage;
    All.Add(wImage);
  }
}

为什么在 XAML 中我对 DistanceToLeft 和 DistanceToTop 的绑定不起作用?!?不是应该自动查看我 ObservableCollection 中使用的对象吗?

编辑:我仍然有我的问题。但现在我知道它与绑定有关。我正在尝试使用 GalaSoft 框架使用 MVVM 模式来实现所有这些。所以首先我将我的 DataContext 设置为我的 MapViewModel。为什么我不能从我的 ObservableCollection 访问 MapItem 的属性?

编辑:最后在 Clemens 和 Rachel 的帮助下,我完成了这个。

我的 MapItem 类:

class MapItem:Image
{
  public LatLon CoordMiddleOfImage { get; set; }
  public LatLon CoordTopLeftOfImage { get; set; }

  public int DistanceToTop
  {
    get { return (int) Canvas.GetTop(this); }
    set { Canvas.SetTop(this, value); }
  }

  public int DistanceToLeft
  {
    get { return (int)Canvas.GetLeft(this); }
    set { Canvas.SetLeft(this, value); }
  }

  public int ZOrder
  {
    get { return Panel.GetZIndex(this); }
    set { Panel.SetZIndex(this, value); }
  }
}

我的 XAML 是这样的:

<ItemsControl ItemsSource="{Binding All}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas ClipToBounds="True"  SnapsToDevicePixels="True"/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

它现在就像一个魅力:-)

4

2 回答 2

5

我不太明白为什么你发明了DistanceToLeftandDistanceToTop属性,然后又在绑定中挣扎。如果您想将图像控件用作项目,为什么不直接应用附加属性Canvas.LeftCanvas.Top

All = new ObservableCollection<Image>(); // no need for derived MapItem
var wSource = new BitmapImage(new Uri(@"ImagePath")); 
var wImage = new Image { Source = wSource }; 
Canvas.SetLeft(wImage, 20);
Canvas.SetTop(wImage, 20);
All.Add(wImage); 

因此,不需要样式:

<ItemsControl ItemsSource="{Binding All}">    
    <ItemsControl.ItemsPanel>    
        <ItemsPanelTemplate>    
            <Canvas />    
        </ItemsPanelTemplate>    
    </ItemsControl.ItemsPanel>    
</ItemsControl> 

但是,您应该考虑创建一个不是控件的真正 ViewModel 类,如下所示:

public class ImageItem
{
    public string Source { get; set; }
    public double Left { get; set; }
    public double Top { get; set; }
}

使用它类似于您的 MapItem 类

All = new ObservableCollection<ImageItem>();
ImageItem image = new ImageItem { Source = @"ImagePath", Left = 20, Top = 20 };
All.Add(image);

您现在可以像这样定义 ItemContainerStyle:

<ItemsControl.ItemContainerStyle>
    <!-- ContentPresenter is the default item container in ItemsControl -->
    <Style TargetType="ContentPresenter">
        <Setter Property="Canvas.Left" Value="{Binding Left}"/>
        <Setter Property="Canvas.Top" Value="{Binding Top}"/>
        <Setter Property="ContentTemplate">                        
            <Setter.Value>
                <DataTemplate>
                    <Image Source="{Binding Source}"/>
                </DataTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ItemsControl.ItemContainerStyle>
于 2012-08-24T17:16:46.663 回答
1

AnItemsControl将每个项目包装在 a 中ContentPresenter,因此 in 中的样式ItemContainerStyle适用于ContentPresenter,而不是Image

如果你TargetType="Image"从你的风格中删除它应该可以正常工作

于 2012-08-24T16:06:52.673 回答