如何设置绑定í;ng在C#中
本文关键字:#237 ng 绑定 何设置 设置 | 更新日期: 2023-09-27 17:58:48
我读了一些书(galli),并在网站上做了一些研究。问题是我想我不明白。
我试图做的是创建一个自定义形状(六边形)的按钮。当用户单击它时,它应该更改"颜色"。
在找到这个和那个之后,我创建了以下内容:
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;
}
}
为了以后使用(当点击按钮-属性更改事件是必要的),我想用它来重置绑定:
private void SetBinding()
{
Binding binding = new Binding();
binding.Path = new PropertyPath("FillProperty");
binding.Source = fillColor;
BindingOperations.SetBinding(hex.polygon, Polygon.FillProperty, binding);
}
我认为问题出在这里:
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 = new Person(){ FirstName = "Test", LastName = "Man"};
这将告诉StackPanel用"Test"answers"Man"填充这两个文本框。
此逻辑扩展到任何类型的UI对象,例如用于设置颜色的SolidColorBrush
。如果您扩展Person类以接受FavColor
属性的SolidColorBrush
,那么您也可以通过为其设置绑定来设置面板的背景,即
<StackPanel x:Name="MyStack" Background="{Binding FavColor}" Orientation="Horizontal">
但是,如前所述,您确实希望将模型(包含要显示的数据的对象,如我们的Person、User或Shape等)和任何类型的View信息完全分离。为了进一步了解如何做到这一点,我将研究模型-视图-视图-模型(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
。
这意味着绑定将转到Source
对象,并在该Source
对象上查找名为FillProperty
的属性,然后将该属性的值传递给多边形的Fill
属性。
这不是您想要的:SolidColorBrush
没有名为FillProperty
的属性(什么都没有),也没有名为Fill
的属性。Fill
是目标属性,而不是源属性。你想要的是:
hex.polygon.Fill = fillColor;
在这种特殊情况下使用绑定是没有用的,因为fillColor
是一个局部变量。您对属性使用绑定,以便在源更改时更新目标(和/或目标更改可能会更新源,具体取决于参数)。
但为了学习Binding
是如何工作的,这也应该是你想要的:
Binding binding = new Binding();
binding.Source = fillColor;
BindingOperations.SetBinding(hex.polygon, Polygon.FillProperty, binding);
我看到一些关于Polygon.FillProperty
和Polygon.Fill
的混淆。Polygon.FillProperty
是一个公共静态只读DependencyProperty
对象,它描述了Polygon的Fill
依赖属性的特性。Polygon
还有一个名为Fill
的正则属性,您可以直接使用它,如我上面所示。按照惯例,公共静态只读DependencyProperty
对象的名称与概念依赖属性相同,后缀为"property",但这不是绝对必需的。