C# 如何设置绑定;C中的ng#
我在网站上读了一些书()并做了一些研究。问题是我想我不明白 我试图做的是创建一个自定义形状(六边形)的按钮。当用户点击它时,它应该改变颜色 在找到和之后,我创建了以下内容:C# 如何设置绑定;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
的常规属性,您可以直接使用它,正如我上面所示。按照惯例,公共静态readonlydependencProperty
对象的名称与概念上的dependency属性相同,后缀为“property”,但不是绝对必需的
该代码创建了一个绑定,其Source
是SolidColorBrush
,其Path
是FillProperty
这意味着绑定将转到源
对象,并在该源
对象上查找名为FillProperty
的属性,然后将该属性的值传递给多边形的Fill
属性
这不是您想要的:SolidColorBrush
没有名为FillProperty
(没有),它也没有名为Fill
的属性<代码>填充
是目标属性,而不是源属性。你想要的就是这个