I want to ask about the right way if I want to create Bindable user control consisting of two controls. I am not sure about what I am doing - whether I do it correctly , because I run into some problems.
Here is what I am trying to do:
Lets call this control ucFlagControl . Create new , custom user control ... Its purpose is to show Color interpretation of logic ( True/ False ) value in variable , type of Bool.
What I used to do before was that I use Rectangle
, and Bind FillProperty
to bool
ean value using Converter
What I did to make it works was , that I made a usercontrol , and put rectangle and label inside than I added this code:
public partial class ucStatusFlag : UserControl
{
public ucStatusFlag()
{
InitializeComponent();
}
public string LabelContent
{
get { return (string)GetValue(LabelContentProperty); }
set
{
SetValue(LabelContentProperty, value);
OnPropertyChanged("LabelContent");
}
}
///in case that I use integer or array
public int BitIndex
{
get { return (int)GetValue(BitIndexProperty); }
set
{
SetValue(BitIndexProperty, value);
OnPropertyChanged("BitIndex");
}
}
public string BindingSource
{
get { return (string)GetValue(BindingSourceProperty); }
set
{
SetValue(BindingSourceProperty, value);
OnPropertyChanged("BindingSource");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
/// <summary>
/// Identified the Label dependency property
/// </summary>
public static readonly DependencyProperty LabelContentProperty =
DependencyProperty.Register("LabelContent", typeof(string), typeof(ucStatusFlag), new PropertyMetadata("LabelContent"));
public static readonly DependencyProperty BitIndexProperty =
DependencyProperty.Register("BitIndex", typeof(int), typeof(ucStatusFlag), new PropertyMetadata(0));
public static readonly DependencyProperty BindingSourceProperty =
DependencyProperty.Register("(BindingSource", typeof(string), typeof(ucStatusFlag), new PropertyMetadata(""));
private void StatusFlag_Loaded(object sender, RoutedEventArgs e)
{
if (BindingSource.Length > 0)
{
Binding bind = new Binding();
string s = LabelContent;
int i = BitIndex;
bind.Converter = new StatusToColor();
bind.Path = new PropertyPath(BindingSource);
bind.ConverterParameter = BitIndex.ToString();
bind.Mode = BindingMode.OneWay;
bind.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
recStatusBit.SetBinding(Rectangle.FillProperty, bind);
}
}
private class StatusToColor : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
byte bDataWordIdx;
byte bDataBitIdx;
Byte.TryParse((string)parameter, out bDataBitIdx);
if (Object.ReferenceEquals(typeof(UInt16[]), value.GetType()))
{
UInt16[] uiaData = (UInt16[])value;
bDataWordIdx = (byte)uiaData[0];
if ((uiaData[bDataBitIdx / 16] >> (bDataBitIdx % 16) & 0x1) == 1)
{
return Brushes.Green;
}
else
{
return Brushes.Red;
}
}
else if (Object.ReferenceEquals(typeof(UInt16), value.GetType()))
{
UInt16 uiaData = (UInt16)value;
if (((uiaData >> bDataBitIdx) & 0x1) == 1)
{
return Brushes.Green;
}
else
{
return Brushes.Red;
}
}
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return 0;
}
}
}
}
Than I realized that I can easily bind content and I do not have to create public static readonly DependencyProperty LabelContentProperty
but just property
public new string Content
{
get { return (string)label.Content; }
set
{
SetValue(label.Content, value);
OnPropertyChanged("Content");
}
}
this overrides the original content so I am able to Bind and/or assign the text of the label in upper level - in e.g. MainWindow.xaml where this user control is put
First question is if this is in this case OK or if there is some background I am not aware of and I should even such small controls do in different way - I would like to make dll. from it an load it to toolbox - I tested it works. And than use it in for example stack panel .
Second question is that I have problem with a rectangle "Fill"
property . I am not able to bind that property like I bind content .
I know that the rectangle is derived from Shape class so I am not sure if it has something to do with this.
If I am able to do the inner binding or connection same as in
Content
I can remove the converters than and just bind it in e.g. MainWindow.xaml file (using the converter and converter parameter )
But FillProperty
does not work for me so I am not sure about my point of view .
Thank you for suggestions
EDIT:
well I am sorry but I did not catch all you want to say in a comment below. Could you please explain closer ? I know that the code above is not the right way to do it ... ? Or can you post any article about it ? my actual code is like this: In a user control ... I removed all the code from code behind ...
' <Label x:Name="lStatusBit" Grid.Column="1" Padding="0" VerticalContentAlignment="Center" Margin="2,1,17,2" />
<Rectangle x:Name="recStatusBit" Margin="0,3,1,7" />'
Content property works, I cant see Rectangle , and rectangle fill property ... Other problem is if I fill in Content property in XAML where my uc is placed , Rectangle disappears .
Fill="{Binding BindingSource, RelativeSource={RelativeSource AncestorType=UserControl}, Converter={StaticResource YourConvertersResourceKey}}"
. Note also that BindingSource is an odd name for a Binding Path, where Binding also has a Source. – Clemens