|
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using Pfz.WpfControls;
using Pfz.Extensions;
namespace Pfz.Databasing.WpfControls
{
/// <summary>
/// Controls bound to a record and capable of finding it by it's key, editing
/// or inserting new ones.
/// </summary>
public class SearchAndEditControl:
UserControl
{
private KeyBoundControl _keyControl = new KeyBoundControl();
private RecordBoundControl _recordControl = new RecordBoundControl();
/// <summary>
/// Creates a new instance of SearchAndEditControl.
/// </summary>
public SearchAndEditControl()
{
var panel = new StackPanel();
var children = panel.Children;
children.Add(_keyControl);
children.Add(_recordControl);
Content = panel;
_keyControl.KeyValuesChanged += _KeyControl_KeyValuesChanged;
CanInsertRecord = true;
DataContextChanged += new System.Windows.DependencyPropertyChangedEventHandler(SearchAndEditControl_DataContextChanged);
}
void SearchAndEditControl_DataContextChanged(object sender, DependencyPropertyChangedEventArgs args)
{
IRecord newValue = args.NewValue as IRecord;
var key = Key;
if (key == null && newValue != null)
{
key = newValue.GetIndex("");
Key = key;
}
if (key != null && newValue != null)
_keyControl.LoadKeyValues(newValue);
}
/// <summary>
/// Gets or sets the Key used by this control.
/// </summary>
public IDatabaseIndex Key
{
get
{
return _keyControl.Key;
}
set
{
_keyControl.Key = value;
if (value == null)
return;
var record = Record;
var recordType = value.RecordType;
if (record != null && !recordType.IsAssignableFrom(record.GetType()))
_SetRecord(null);
var bindings = PropertyBindings;
if (bindings.Count == 0)
{
var primaryKeyProperty = Databasing.Record.GetPrimaryKeyProperty(recordType);
var keyProperties = value.Properties;
foreach(var triplet in Databasing.Record.GetPropertiesDictionary(recordType))
{
var property = triplet.Value.Property;
if (property == primaryKeyProperty)
continue;
if (keyProperties.ContainsKey(property.Name))
continue;
var binding = new PropertyBinding();
binding.Property = property;
bindings.Add(binding);
}
}
}
}
/// <summary>
/// Gets or sets the propeties this control will display.
/// Example as string property:
/// FullTypeName.* (which will get all properties)
/// FullTypeName:PropertyName;OtherPropertyName
/// FullTypeName:PropertyName=Display name;OtherPropertyName=Other display name
/// FullTypeName.PropertyName=Display name;OtherFullTypeName.PropertyName=Other display name
/// </summary>
[TypeConverter(typeof(PropertyBindingsTypeConverter))]
public ObservableCollection<PropertyBinding> PropertyBindings
{
get
{
return _recordControl.PropertyBindings;
}
set
{
_recordControl.PropertyBindings = value;
}
}
/// <summary>
/// Gets or sets the record of this control.
/// </summary>
public IRecord Record
{
get
{
return DataContext as IRecord;
}
set
{
DataContext = value;
}
}
/// <summary>
/// Gets or sets a value indicating that, by default, this is a read-only control.
/// By default means, if it search the record. If you set a record to it, the state
/// of the record will determine if it is read-only or not.
/// </summary>
public bool IsReadOnlyByDefault { get; set; }
/// <summary>
/// Gets or sets a value indicating if this control can automatically create
/// a new record when one is not found. The default value is true.
/// </summary>
[DefaultValue(true)]
public bool CanInsertRecord { get; set; }
void _KeyControl_KeyValuesChanged(object sender, KeyValuesChangedEventArgs e)
{
var values = e.Values;
foreach(var value in values)
{
if (value == null)
{
_SetRecord(null);
return;
}
}
var key = Key;
var record = key.TryGetRecord(values);
if (!IsReadOnlyByDefault)
{
if (record != null)
record = record.CreateUpdateRecord();
else
if (CanInsertRecord)
{
record = Databasing.Record.Create(key.RecordType);
int valueIndex = -1;
foreach(var property in key.Properties.Values)
{
valueIndex++;
object value = values[valueIndex];
property.SetValue(record, value);
}
}
}
_SetRecord(record);
}
private void _SetRecord(IRecord record)
{
var setter = this.FindPropertySetter(FrameworkElement.DataContextProperty);
if (setter == null)
setter = this;
setter.SetValue(FrameworkElement.DataContextProperty, record);
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I started to program computers when I was 11 years old, as a hobbyist, programming in AMOS Basic and Blitz Basic for Amiga.
At 12 I had my first try with assembler, but it was too difficult at the time. Then, in the same year, I learned C and, after learning C, I was finally able to learn assembler (for Motorola 680x0).
Not sure, but probably between 12 and 13, I started to learn C++. I always programmed "in an object oriented way", but using function pointers instead of virtual methods.
At 15 I started to learn Pascal at school and to use Delphi. At 16 I started my first internship (using Delphi). At 18 I started to work professionally using C++ and since then I've developed my programming skills as a professional developer in C++ and C#, generally creating libraries that help other developers do their work easier, faster and with less errors.
Want more info or simply want to contact me?
Take a look at:
http://paulozemek.azurewebsites.net/
Or e-mail me at: paulozemek@outlook.com
Codeproject MVP 2012, 2015 & 2016
Microsoft MVP 2013-2014 (in October 2014 I started working at Microsoft, so I can't be a Microsoft MVP anymore).