I've read some books (galli) and did some research here on the site. The problem is I think I didn't understand it.
What I tried to do is to create a button of a custom shape (hexagon). When the user clicks it, it should change the Color.
After finding this and that, I created the following:
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;
}
I also have a hexagon class:
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;
}
}
For later use (when clicking the button - property changed event necessary) I wanted to use this to reset the binding:
private void SetBinding()
{
Binding binding = new Binding();
binding.Path = new PropertyPath("FillProperty");
binding.Source = fillColor;
BindingOperations.SetBinding(hex.polygon, Polygon.FillProperty, binding);
}
I think the problem is somewhere in here:
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?