Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何设置绑定&#x;C中的ng#_C#_Wpf_Button_Binding - Fatal编程技术网

C# 如何设置绑定&#x;C中的ng#

C# 如何设置绑定&#x;C中的ng#,c#,wpf,button,binding,C#,Wpf,Button,Binding,我在网站上读了一些书()并做了一些研究。问题是我想我不明白 我试图做的是创建一个自定义形状(六边形)的按钮。当用户点击它时,它应该改变颜色 在找到和之后,我创建了以下内容: public class hexButton : System.Windows.Controls.Button { public SolidColorBrush borderColor { get; set; } public SolidColorBrush fillColor {get;set;}

我在网站上读了一些书()并做了一些研究。问题是我想我不明白

我试图做的是创建一个自定义形状(六边形)的按钮。当用户点击它时,它应该改变颜色

在找到和之后,我创建了以下内容:

 public class hexButton : System.Windows.Controls.Button
{
    public SolidColorBrush borderColor { get; set; }
    public SolidColorBrush fillColor {get;set;}
    public int Height { get; private set; }
    public int Width { get; private set; }
    public Point Location { get; private set; }
    private Hexagon hex;

    public hexButton() : this(50,0,0,Colors.Yellow, Colors.Brown){}    

    public hexButton(int sideLenght, int positionX, int positionY, Color border, Color fill):base()
    {
        borderColor = new SolidColorBrush(border);
        fillColor = new SolidColorBrush(fill);
        hex = new Hexagon(sideLenght, positionX, positionY);

        Binding binding = new Binding();
        binding.Path = new PropertyPath("FillProperty");
        binding.Source = fillColor;
        BindingOperations.SetBinding(hex.polygon, Polygon.FillProperty, binding);

        ControlTemplate t = new ControlTemplate(typeof(Button));
        FrameworkElementFactory fef = new FrameworkElementFactory(typeof(Polygon));
        fef.Name = "Polygon";
        fef.SetValue(Polygon.PointsProperty, hex.polygon.Points);
        fef.SetBinding(Polygon.FillProperty, binding); //doesent work
        fef.SetValue(Polygon.StrokeThicknessProperty, hex.polygon.StrokeThickness);
        //fef.SetValue(Polygon.FillProperty, fillColor); // works at least for the constructor
        fef.SetValue(Polygon.StrokeProperty, borderColor);
        t.VisualTree = fef;

        Style hexButtonStyle = new Style(typeof(Button));
        hexButtonStyle.Setters.Add(new Setter(Button.TemplateProperty, t));

        this.Style = hexButtonStyle;
        this.Height = hex.Y_Max - hex.Y_Min;
        this.Width = hex.X_Max - hex.X_Min;
        this.Location = hex.location;
    }
我还有一门六边形课程:

    public class Hexagon
{
    private int _Height;
    private int _Diameter;
    private int _SideLenght;
    public Polygon polygon { get; set; }
    public int Y_Min { get; private set; }
    public int Y_Max { get; private set; }
    public int X_Min { get; private set; }
    public int X_Max { get; private set; }
    public Point location { get; set; }

    public Hexagon() : this(30) { }

    public Hexagon(int sideLenght): this (sideLenght,0,0) { }

    public Hexagon(int sideLenght, Point location): this(sideLenght,(int)location.X, (int)location.Y){}

    public Hexagon(int sideLenght, int locationX, int locationY)
    {
        if (sideLenght <= 0)
        {
            sideLenght = 30;
        }
        _SideLenght = sideLenght;
        calcHeight();
        calcDiameter();
        location = new Point(locationX, locationY);
        polygon = new Polygon();
        polygon.Points.Clear();
        polygon.StrokeThickness = 4;
        createHexPolygon();
    }

    private void calcHeight()
    {
        //h = (√3)s
        _Height = Convert.ToInt32(Math.Pow(3,0.5)*_SideLenght);
    }

    private void calcDiameter()
    {
        _Diameter = 2 * _SideLenght;
    }

    private void createHexPolygon()
    {   //        0           1
        //         __________
        //        /          \
        //       /            \
        //      /              \  2
        //    5 \              /
        //       \            /
        //        \__________/
        //        4           3

        Point p = new Point();
        p.X = _SideLenght / 2;
        p.Y = 0;
        p.X = p.X + location.X + 2; // +2 =offset von StrokeThickness (siehe konstruktor)
        p.Y = p.Y + location.Y + 2;
        polygon.Points.Add(p);
        p.X = _SideLenght + (_SideLenght / 2);
        p.Y = 0;
        p.X = p.X + location.X + 2;
        p.Y = p.Y + location.Y + 2;
        polygon.Points.Add(p);
        p.X = _Diameter;
        p.Y = _Height / 2;
        p.X = p.X + location.X + 2;
        p.Y = p.Y + location.Y + 2;
        polygon.Points.Add(p);
        p.X = _SideLenght + (_SideLenght / 2);
        p.Y = _Height;
        p.X = p.X + location.X + 2;
        p.Y = p.Y + location.Y + 2;
        polygon.Points.Add(p);
        p.X = _SideLenght / 2;
        p.Y = _Height;
        p.X = p.X + location.X + 2;
        p.Y = p.Y + location.Y + 2;
        polygon.Points.Add(p);
        p.X = 0;
        p.Y = _Height / 2;
        p.X = p.X + location.X + 2;
        p.Y = p.Y + location.Y + 2;
        polygon.Points.Add(p);

        X_Min = (int)polygon.Points[5].X;
        X_Max = (int)polygon.Points[2].X + 2;
        Y_Min = (int)polygon.Points[0].Y;
        Y_Max = (int)polygon.Points[3].Y + 2;
    }

}
我认为问题就在这里:

Binding binding = new Binding();
        binding.Path = new PropertyPath("FillProperty");
        binding.Source = fillColor;
        BindingOperations.SetBinding(hex.polygon, Polygon.FillProperty, binding);

        //....

        fef.SetBinding(Polygon.FillProperty, binding);


1. Why is the binding not working?
2. What do I need to do to make it work?
3. I read somewhere (don't know where) that creating styles and bindings in code (behind) is not really recommended
    - What would be another way to do this?
    - Why is it not recommended?

在非常基本的级别上,绑定是通过使用UI元素的
DataContext
属性来完成的。例如,如果您有一个
Person
类:

public class Person
{
     public string FirstName {get;set;}
     public string LastName {get;set;}
}
然后可以使用绑定将这些属性绑定到UI元素,而无需显式设置它们。例如,如果您有一个
StackPanel

<StackPanel x:Name="MyStack" Orientation="Horizontal">
    <TextBlock Text="{Binding FirstName}"/>
    <TextBlock Text="{Binding LastName}"/>
</StackPanel>

此XAML将在设置的DataContext中查找名为FirstName或LastName的任何属性。因此,通过将
DataContext
设置为
Person
对象,它可以显示我们指定的数据

MyStack.DataContext=newperson(){FirstName=“Test”,LastName=“Man”}

这将告诉StackPanel用“Test”和“Man”填充这两个文本框

此逻辑扩展到任何类型的UI对象,例如用于设置颜色的
SolidColorBrush
。如果扩展Person类以接受
FavColor
属性的
SolidColorBrush
,则可以通过设置面板的绑定来设置面板的背景,即


但是,如前所述,您确实希望将模型(包含要显示的数据的对象,如我们的人、用户或形状等)与任何类型的视图信息完全分开。为了更深入地了解如何做到这一点,我将研究模型-视图-模型(MVVM)模式,它主要关注XAML数据绑定。有很多很好的教程,我使用视频示例来帮助我理解,因此可能也值得搜索这些教程来扩展您的知识。

在非常基本的级别上,绑定是通过使用UI元素的
DataContext
属性来完成的。例如,如果您有一个
Person
类:

public class Person
{
     public string FirstName {get;set;}
     public string LastName {get;set;}
}
Binding binding = new Binding();
binding.Path = new PropertyPath("FillProperty");
binding.Source = fillColor;
BindingOperations.SetBinding(hex.polygon, Polygon.FillProperty, binding);
然后可以使用绑定将这些属性绑定到UI元素,而无需显式设置它们。例如,如果您有一个
StackPanel

<StackPanel x:Name="MyStack" Orientation="Horizontal">
    <TextBlock Text="{Binding FirstName}"/>
    <TextBlock Text="{Binding LastName}"/>
</StackPanel>

此XAML将在设置的DataContext中查找名为FirstName或LastName的任何属性。因此,通过将
DataContext
设置为
Person
对象,它可以显示我们指定的数据

MyStack.DataContext=newperson(){FirstName=“Test”,LastName=“Man”}

这将告诉StackPanel用“Test”和“Man”填充这两个文本框

此逻辑扩展到任何类型的UI对象,例如用于设置颜色的
SolidColorBrush
。如果扩展Person类以接受
FavColor
属性的
SolidColorBrush
,则可以通过设置面板的绑定来设置面板的背景,即

但是,如前所述,您确实希望将模型(包含要显示的数据的对象,如我们的人、用户或形状等)与任何类型的视图信息完全分开。为了更深入地了解如何做到这一点,我将研究模型-视图-模型(MVVM)模式,它主要关注XAML数据绑定。有很多很好的教程,我用视频例子来帮助我理解,所以可能也值得搜索这些来扩展你的知识

Binding binding = new Binding();
binding.Path = new PropertyPath("FillProperty");
binding.Source = fillColor;
BindingOperations.SetBinding(hex.polygon, Polygon.FillProperty, binding);
该代码创建了一个绑定,其
Source
SolidColorBrush
,其
Path
FillProperty

这意味着绑定将转到
对象,并在该
对象上查找名为
FillProperty
的属性,然后将该属性的值传递给多边形的
Fill
属性

这不是您想要的:
SolidColorBrush
没有名为
FillProperty
(没有),它也没有名为
Fill
的属性<代码>填充
是目标属性,而不是源属性。你想要的是:

hex.polygon.Fill = fillColor;
在这种特殊情况下使用绑定是没有用的,因为
fillColor
是一个局部变量。您可以对属性使用绑定,以便在源更改时更新目标(和/或目标更改可能会更新源,具体取决于参数)

但是为了了解
绑定如何工作,这也应该满足您的需要:

Binding binding = new Binding();
binding.Source = fillColor;
BindingOperations.SetBinding(hex.polygon, Polygon.FillProperty, binding);
我看到一些关于
Polygon.FillProperty
Polygon.Fill
的混淆<代码>多边形。FillProperty
是一个
Polygon
还有一个名为
Fill
的常规属性,您可以直接使用它,正如我上面所示。按照惯例,公共静态readonly
dependencProperty
对象的名称与概念上的dependency属性相同,后缀为“property”,但不是绝对必需的

该代码创建了一个绑定,其
Source
SolidColorBrush
,其
Path
FillProperty

这意味着绑定将转到
对象,并在该
对象上查找名为
FillProperty
的属性,然后将该属性的值传递给多边形的
Fill
属性

这不是您想要的:
SolidColorBrush
没有名为
FillProperty
(没有),它也没有名为
Fill
的属性<代码>填充
是目标属性,而不是源属性。你想要的就是这个