【问题标题】:Binding a list of item in other controls than ListView/ListBox在 ListView/ListBox 以外的其他控件中绑定项目列表
【发布时间】:2014-11-18 20:56:02
【问题描述】:

我的应用程序是 Windows Phone 8.1 中的通用应用程序。

我想在屏幕上画一些圆圈,但要根据我的 ViewModel 中的数据设置它们的边距,我知道为一个项目做这件事很热,但对其中的很多项目都不做。

所以这就是没有任何绑定的样子:

<Grid>
    <Canvas>
        <!-- Background -->
        <Rectangle Width="400" Height="400" Fill="Gray"/>
        <!-- List of circles -->
        <Ellipse Fill="White" Width="10" Height="10" Margin="40,300,0,0"/>
        <Ellipse Fill="White" Width="10" Height="10" Margin="80,250,0,0"/>
        <Ellipse Fill="White" Width="10" Height="10" Margin="120,240,0,0"/>
        <Ellipse Fill="White" Width="10" Height="10" Margin="160,275,0,0"/>
        <Ellipse Fill="White" Width="10" Height="10" Margin="200,275,0,0"/>
        <Ellipse Fill="White" Width="10" Height="10" Margin="240,130,0,0"/>
        <Ellipse Fill="White" Width="10" Height="10" Margin="280,150,0,0"/>
        <Ellipse Fill="White" Width="10" Height="10" Margin="320,200,0,0"/>
        <Ellipse Fill="White" Width="10" Height="10" Margin="360,220,0,0"/>
    </Canvas>
</Grid>

但我不想有多个这样的控件,我在我的 ViewModel 中做了这个:

public ObservableCollection<Point> Points { get; set; }
    public ObservableCollection<Thickness> Thickness { get; set; }
    public MainViewModel ()
    {
        if (Windows.ApplicationModel.DesignMode.DesignModeEnabled)
        {
            Points = new ObservableCollection<Point>();
            Points.Add(new Point(40, 250));
            Points.Add(new Point(60, 300));
            Points.Add(new Point(90, 150));

            Thickness = new ObservableCollection<Thickness>();
            foreach(Point point in Points)
            {
                Thickness.Add(new Thickness(point.X, point.Y, 0, 0));
            }
        }
    }

我想为每个圆(或椭圆)绑定属性“厚度”中设置的边距。 画布中的圆圈数必须与 ObservableCollection "Thickess" 中的项目数相同。

我不知道如何说得足够清楚,所以如果您有一些问题,请不要犹豫。

【问题讨论】:

标签: c# list xaml binding windows-phone-8.1


【解决方案1】:

保证金不是设置头寸的好方法。在 Canvas 中,您通常会设置 Top 和 Left 属性,但对于您的情况,我建议使用 RenderTransform。

要显示基于绑定的对象列表,您需要将它们托管在容器控件中,例如 ItemsControl。默认情况下,ItemsControl 使用一个面板,该面板将按顺序排列项目,但您可以将其替换为 Canvas 并将您的 Ellipses 添加为绑定的数据对象:

<ItemsControl x:Name="ic">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Ellipse StrokeThickness="{Binding Thickness}" Width="10" Height="10" Stroke="{Binding Fill}">
                <Ellipse.RenderTransform>
                    <TranslateTransform X="{Binding Left}" Y="{Binding Top}"/>
                </Ellipse.RenderTransform>
            </Ellipse>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Canvas.Left 和 Canvas.Top 是指向 Ellipse 父级的附加属性,因此在 DataTemplate 中设置它们不会有任何效果。我们可以跳过一些环节来将它们设置到容器上,但设置转换更容易。

如果您更喜欢设置 Margin,则可以改为绑定它:

<Ellipse  Margin="{Binding Margin}" StrokeThickness="{Binding Thickness}" Width="10" Height="10" Stroke="{Binding Fill}" />

无论哪种方式,使用您需要绑定的属性创建一个类,并将该类型的 ObservableCollection 绑定到 ItemsControl。下面是一个演示这两种定位技术的速记:

class CircleObject
{
    public float Top { get; set; }
    public float Left { get; set; }
    public double Thickness { get; set; }

    public Thickness Margin {
        get { 
            return new Thickness(Left, Top, 0, 0);
        }
    }
    public Brush Fill { get; set; }
}
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
    ObservableCollection<CircleObject> circles;
    public MainPage()
    {
        this.InitializeComponent();

        this.NavigationCacheMode = NavigationCacheMode.Required;

        SolidColorBrush b = new SolidColorBrush(Colors.White);
        circles = new ObservableCollection<CircleObject>();
        circles.Add(new CircleObject() { Left = 40, Top = 300, Thickness = 10, Fill = b });
        circles.Add(new CircleObject() { Left = 80, Top = 250, Thickness = 20, Fill = b });
        circles.Add(new CircleObject() { Left = 120, Top = 240, Thickness = 30, Fill = b });
        circles.Add(new CircleObject() { Left = 160, Top = 275, Thickness = 20, Fill = b });
        circles.Add(new CircleObject() { Left = 200, Top = 275, Thickness = 30, Fill = b });
        circles.Add(new CircleObject() { Left = 240, Top = 130, Thickness = 40, Fill = b });
        circles.Add(new CircleObject() { Left = 280, Top = 150, Thickness = 50, Fill = b });
        circles.Add(new CircleObject() { Left = 320, Top = 200, Thickness = 40, Fill = b });
        circles.Add(new CircleObject() { Left = 360, Top = 220, Thickness = 30, Fill = b });

        ic.ItemsSource = circles;
    }

【讨论】:

    【解决方案2】:

    使用ItemsControl 并将ItemsSource 绑定到您的收藏。

    <Grid>
        <Canvas>
            <!-- Background -->
            <Rectangle Width="400" Height="400" Fill="Gray"/>
            <!-- List of circles -->
            <ItemsControl ItemsSource="{Binding Path=Thickness}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Ellipse Fill="White" Width="10" Height="10" Margin="{Binding}"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Canvas>
    </Grid>
    

    【讨论】:

      猜你喜欢
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多