从阵列进行绑定更新

时间:2013-02-05 16:25:43

标签: c# .net wpf arrays data-binding

我不确定数组是否真的是这里的问题,但我有一个矩形,我想在引发MouseUp事件时从窗口的一侧移动到另一侧。我将此矩形绑定到数组元素,MouseUp事件处理程序方法更改该数组的值。我知道处理程序方法是有效的,因为它可以很好地拉出一个消息框,只是不切换矩形的位置。

注意:数组是必需的,这只是测试这些概念的代码,而不是我的实际项目。

也非常感谢解决这个问题的最简单方法。

C#代码:

namespace WPFTestingApplication
{
    public static class GridProperties
    {
        public static int[] gridColumn = { 0 };
    }

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Rect_MouseUp_1(object sender, MouseButtonEventArgs e)
        {
            GridProperties.gridColumn[0] = 1;
        }
    }
}

XAML代码:

<Window x:Class="WPFTestingApplication.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WPFTestingApplication"
        Title="MainWindow" Height="200" Width="400">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Rectangle Name="Rect" Grid.Column="{Binding [0], Source={x:Static local:GridProperties.gridColumn}, Mode=OneWay}" Fill="DarkGray" Margin="5" MouseUp="Rect_MouseUp_1"/>
    </Grid>
</Window>

2 个答案:

答案 0 :(得分:0)

好的,所以我们必须放弃Windows窗体心态(heh)。在WPF中,您需要考虑功能外观之间的分离。也就是说,您允许代码(c#)确定功能方面,然后在xaml中进行一些模板化以使其具有外观。

您真正想要的功能是 Thumb 。拇指已经内置了拖动功能,因此您只需要创建一个模板来为其提供外观。

首先来看看这个:

http://wpf.2000things.com/tag/dragging/

我会通过创建你自己的类来实现这一点,这个类派生于拇指,如下所示:

// Although the visual template we're applying is a circle,
// the FUNCTIONALITY is primarily that of a thumb. So that's what 
// we'll use. A thumb is essentially a 'draggable thing'.
class DragCircle : System.Windows.Controls.Primitives.Thumb
{      
    public DragCircle()
    {
        // Thumbs _track_ movement, but they don't actually move. We have to handle this ourselves.
        // We do this by setting the Canvas.Left/Canvas.Top attached properties. Of course, for this
        // to work our DragCircle has to be placed on a Canvas, otherwise there's no-one to read the property.
        // IMPORTANT! In order to read the Canvas position later, it needs to have a record in the WPF 
        // dependency property table. So for now we'll just set it to '0' as a default.
        Canvas.SetLeft (this, 0);
        Canvas.SetTop (this, 0);

        // The drag-delta event occurs when the Thumb is dragged. 'delta' represents "change" just like
        // we all learned in calculus.
        this.DragDelta += new System.Windows.Controls.Primitives.DragDeltaEventHandler(DragCircle_DragDelta);
    }

    void DragCircle_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
    {
        // Read the Canvas location from the WPF database.
        Double currentX = Canvas.GetLeft(this);
        Double currentY = Canvas.GetTop(this);

        // Now update the canvas attached properties using the drag-delta ('change in position').
        // Note that Canvas.SetLeft is just a helper function that maps to the attached property: 
        //  this.SetValue(Canvas.TopProperty, SOME_VALUE);
        Canvas.SetLeft(this, currentX + e.HorizontalChange);
        Canvas.SetTop(this, currentY + e.VerticalChange);
    }
}

然后只需创建一个这样的模板:

<Window.Resources>
    <Style TargetType="lol:DragCircle">
        <Setter Property="Foreground" Value="LightGreen" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="lol:DragCircle">
                    <Ellipse Width="20" Height="20" Fill="{TemplateBinding Foreground}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Foreground" Value="Orange" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

现在把它放到画布上,你就完成了。

<Canvas>
    <lol:DragCircle Canvas.Left="100" Canvas.Top="200" />
    <lol:DragCircle Canvas.Left="50" Canvas.Top="50" />
    <lol:DragCircle Canvas.Left="300" Canvas.Top="400" />
</Canvas>

答案 1 :(得分:0)

数组就是问题所在。你应该阅读INotifyPropertyChanged,你绑定的任何内容都将在没有它的情况下更新。

如果可以,请将数组更改为ObservableCollection,以便对其元素进行更改INotifyPropertyChanged。您可以将其编入索引,就像它是一个数组一样。

您可能在将属性集存储在静态类中时遇到问题。静态类和属性没有属性更改通知。如果GridProperties可能是窗口类的属性,那将更容易。然后,将窗口的DataContext设置为自身。

这样的东西适用于你的例子。但是不知道你的实际项目中是否有更复杂的东西。

C#:

public partial class MainWindow : Window
{
    public ObservableCollection<int> GridProperties { get; private set; }

    public MainWindow()
    {
        InitializeComponent();
        GridProperties = new ObservableCollection<int>();
        GridProperties.Add(0);
        DataContext = this;
    }

    private void Rect_MouseUp_1(object sender, MouseButtonEventArgs e)
    {
        GridProperties[0] = 1;
    }
}

XAML:

<Grid>
    <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Rectangle Name="Rect" Grid.Column="{Binding GridProperties[0]}" Fill="DarkGray" Margin="5" MouseUp="Rect_MouseUp_1"/>
</Grid>