Simple object building by xaml - c#

I have a simple class and I want to simply create instances of my class via xaml. But I'm still getting errors like: "'Test' member is not valid because it does not have a qualifying type name."
UserControl1.xaml.cs:
namespace WpfTestApplication1
{
public class UserControl1 : UserControl
{
public string Test { get; set; }
public UserControl1()
{
}
}
}
UserControl1.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfTestApplication1">
<local:UserControl1>
<Setter Property="Test" Value="aaaa" />
</local:UserControl1>
</ResourceDictionary>
Please, help.

The way you have set the Property on your UserControl is not valid. You have set the Content of your UserControl by putting Setter inside the nodes.
First define Test as DependencyProperty if you want it to be binding target and then set it directly on UserControl as
<local:UserControl1 Test="aaaa"/>

Try to use DependencyProperty instead of default property.

As #us3r said...DependencyProperty is what you are looking for.
What you have to do is:
// Dependency Property
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register( "Test", typeof(string),
typeof(UserControl1 ));
// .NET Property wrapper
public string Test
{
get { return GetValue(TestProperty ).; }
set { SetValue(TestProperty , value); }
}

Finally I found it out.
I defined the control in xaml as
<local:UserControl1 x:Key="xxx" Test="aaaa"/>
Without using setter and property statements, just by directly defining the property.
Thanks for help!

Related

Access Indirect property from XAML - WPF

I have a Control class named MyControl and it has direct bool property AccessDirectProperty and an Object MyControlSettings
public class MyControl : Control
{
public bool AccessDirectProperty
{
get; set;
}
public MyControlSettings ControlSettings
{
get;set;
}
}
Please find the MyControlSettings class details
public class MyControlSettings
{
public bool AccessIndirectProperty
{
get;set;
}
}
Direct property AccessDirectProperty can be accessible from XAML without any error.
<Window>
<Grid>
<local:MyControl AccessDirectProperty="True"/>
</Grid>
</Window>
But I cannot access the property AccessIndirectProperty from the object ControlSettings in XAML. The below code fails to do that.
<Window>
<Grid>
<local:MyControl AccessDirectProperty="True" ControlSettings.AccessIndirectProperty=""/>
</Grid>
</Window>
Can anyone help me on this?
I'm afraid that XAML does not support accessing "nested" properties.
You could, however, make ControlSettings an independent class with attached properties:
public class ControlSettings : DependencyObject
{
public static readonly DependencyProperty AccessIndirectPropertyProperty =
DependencyProperty.RegisterAttached(
"AccessIndirectProperty", typeof(bool), typeof(ControlSettings),
new PropertyMetadata(false));
public static bool GetAccessIndirectProperty(DependencyObject d)
{
return (bool) d.GetValue(AccessIndirectPropertyProperty);
}
public static void SetAccessIndirectProperty(DependencyObject d, bool value)
{
d.SetValue(AccessIndirectPropertyProperty, value);
}
}
Then,
<local:MyControl x:Name="myControl"
AccessDirectProperty="True"
ControlSettings.AccessIndirectProperty="True" />
would set a value which could be accessed via
var p = ControlSettings.GetAccessIndirectProperty(myControl); // yields True
Now, on a technical level, the following is not useful to modify a property of an existing MyControlSettings instance provided through MyControl.ControlSettings. However, if your use case allows creating and assigning an entirely new MyControlSettings instance to MyControl.ControlSettings, you can do so in XAML:
<local:MyControl>
<ControlSettings>
<local:MyControlSettings AccessIndirectProperty="true" />
</ControlSettings>
</local:MyControl>
A side note: The term "ControlSettings" suggest to me that you want to kind of "package" control settings/properties in some kind of MyControlSettings "container". Now, i don't know why and what the motivation for this is, but keep in mind that choosing this approach can make it very hard or even impossible to use data bindings in a meaningful way where such a settings property is supposed to be the binding target. If you want to be able to use individual settings as binding target (like AccessIndirectProperty="{Binding Path=Source}"), i would rather suggest your MyControl exposes those settings individually as DependencyProperties.

Numeric type as DependencyProperty

How to register custom property which based on numeric type?
public class NumberBox : TextBox
{
public static readonly DependencyProperty FormatProperty = DependencyProperty.Register("FormatValue", typeof(Type), typeof(NumberBox), new UIPropertyMetadata(default(Double)));
public Type FormatValue
{
get
{
return (Type)GetValue(FormatProperty);
}
set
{
SetValue(FormatProperty, value);
}
}
}
XAML
<nb:NumberBox FormatValue="{System:Int32}"/>
I am sure, that is not perfect, but I really don't know how it make workable.
UPDATE:
Basically, me need to have a way to set the type of my number box. For example, if I need to use Double NumberBox I just set FormatValue="Double"
First issue is default metadata provided in last parameter of DP identifier is incorrect.
Instead of
new UIPropertyMetadata(default(Double)),
it should be
new UIPropertyMetadata(typeof(Double))
Second issue in XAML. Use x:Type to pass type.
<nb:NumberBox xmlns:sys="clr-namespace:System;assembly=mscorlib"
FormatValue="{x:Type sys:Int32}"/>
From here http://msdn.microsoft.com/en-us/library/ee792002%28v=vs.110%29.aspx, the types are x:Int32, x:Double, ...
So you want to use:
<nb:NumberBox FormatValue="{x:Type x:Int32}"/>
In the general sense, you would have to include the namespace in the XAML:
<Window ...
xmlns:ns="clr-namespace:MyNamepsace;assembly=MyAssembly"
>
<nb:NumberBox FormatValue="{x:Type ns:MyType}"/>
</Window>

How to create your own properties for element in SilverLight

Can someone help me with this question?) In My XAML I have Listbox element. I want to add my user property into it(in my case - ConnectorStyle)
My XAML code:
<ListBox ItemsSource="{Binding Nodes}" ItemsPanel="{StaticResource CanvasItemsPanelTemplate}"
ItemTemplate="{StaticResource NodePictureTemplate}"
ItemContainerStyle="{StaticResource CanvasItemStyle}"
ConnectorStyle="{StaticResource ConnectorLineStyle}"/>
In my Model I have prepared this property:
public partial class MainPage : UserControl
{
public static readonly DependencyProperty ConnectorStyleProperty = DependencyProperty.Register(
"ConnectorStyle", typeof(Style), typeof(NodePicture), null);
public MainPage()
{
InitializeComponent();
}
public Style ConnectorStyle
{
get { return (Style)GetValue(ConnectorStyleProperty); }
set { SetValue(ConnectorStyleProperty, value); }
}
}
But I is a mistake - Cannot resolve ConnectorStyle.
Is there a simple (or a right way ) way of doing this?
There are two ways to do this: Either you can write a subclass for the ListBox that adds the DependencyProperty or you can write an attached property.
In your case you probably want to write a subclass that adds the property. Try something like this:
public class MyListBox : ListBox
{
public static readonly DependencyProperty ConnectorStyleProperty = DependencyProperty.Register(
"ConnectorStyle", typeof(Style), typeof(MyListBox), null);
public Style ConnectorStyle
{
get { return (Style)GetValue(ConnectorStyleProperty); }
set { SetValue(ConnectorStyleProperty, value); }
}
}
This will add a new type of ListBox that you can add in your xaml code. It will have all the same properties as a regular ListBox, but it will also have the ConnectorStyle property.
If you need to respond to changes to the ConnectorStyle property in your listbox then you should change the code for the Dependency Property, but that is outside the scope of this question.
And in XAML it shoul be :
<local:ListBoxEx
ConnectorStyle="{StaticResource ConnectorLineStyle}"/>

Specify which Property goes between the opening and closing tag in Xaml

Consider the following Xaml
<Grid>
<TextBox>Text</TextBox>
<Button>Content</Button>
</Grid>
It will set the
Text Property of a TextBox (only WPF)
Content Property of a Button
Children Property of a Grid
But how is this specified? How do you specify which Property that goes between the opening and closing tag in Xaml?
Is this set by some metadata in the Dependency Property or what?
Thanks
There is a ContentPropertyAttribute that is applied to a class. WPF/Silverlight will use reflection to determine which property to use.
If you want to do this with a custom class, you can do it like so:
[ContentProperty("Bar")]
public class Foo : Control
{
public static DependencyProperty BarProperty = DependencyProperty.Register(
"Bar",
typeof(int),
typeof(Foo),
new FrameworkPropertyMetaData(0));
public int Bar
{
get { return (int)GetValue(BarProperty); }
set { SetValue(BarProperty, value); }
}
}
Then you could specify it in XAML like so:
<lcl:Foo>12</lcl:Foo>
Update
Since it is using reflection, you don't really need to do a DependencyProperty. For instance, this will also work:
[ContentProperty("Bar")]
public class Foo : Control
{
public int Bar { get; set; }
}

How to achieve databinding with a user control in WPF?

I'm fairly new to WPF and I have some problems getting databinding to work as I want. I've written a user control which contains a TextBox whose Text-Property I want to bind to a property of my UserControl, which I want to bind again to something else.
What am I missing?
XAML
<!-- User Control -->
<TextBox Text="{Binding Path=TheText}" />
<!-- Window -->
<WpfApplication1:SomeControl TheText="{Binding Path=MyStringProp}" />
C#
// User Control ----
public partial class SomeControl : UserControl
{
public DependencyProperty TheTextProperty = DependencyProperty
.Register("TheText", typeof (string), typeof (SomeControl));
public string TheText
{
get
{
return (string)GetValue(TheTextProperty);
}
set
{
SetValue(TheTextProperty, value);
}
}
public SomeControl()
{
InitializeComponent();
DataContext = this;
}
}
// Window ----
public partial class Window1 : Window
{
private readonly MyClass _myClass;
public Window1()
{
InitializeComponent();
_myClass = new MyClass();
_myClass.MyStringProp = "Hallo Welt";
DataContext = _myClass;
}
}
public class MyClass// : DependencyObject
{
// public static DependencyProperty MyStringPropProperty = DependencyProperty
// .Register("MyStringProp", typeof (string), typeof (MyClass));
public string MyStringProp { get; set; }
// {
// get { return (string)GetValue(MyStringPropProperty); }
// set { SetValue(MyStringPropProperty, value); }
// }
}
Best RegardsOliver Hanappi
PS: I've tried to implement the INotifyPropertyChanged interface on my user control, but it did not help.
You want to bind the Text property of your TextBox back to the TheText property of the UserControl it lives in, right? So you need to tell the binding where the property lives. There's a couple of ways to do this (you can do it with a RelativeSource using FindAncestor) but the easiest way is to give the UserControl a "name" in the XAML and bind using element binding:
<UserControl ...
x:Name="me" />
<TextBox Text="{Binding TheText,ElementName=me}" />
</UserControl>
Now your TextBox will reflect the value you've assigned (or bound) to your "SomeControl.TheText" property - you needn't change any of your other code, although you'll probably want to implement INotifyPropertyChanged on your underlying MyClass object so that the binding knows when the property has changed.
Matt has provided a solution to your problem. Here is a little more explanation and a hint to stop this problem in future.
As SomeControl.DataContext is set in the SomeControl constructor, the window's binding TheText="{Binding Path=MyStringProp}" has a Source of type SomeControl, not MyClass as you intended.
Any bindings that fail at runtime cause debug messages to be logged to the output panel of Visual Studio. In this case, you would have seen that no such property 'MyStringProp' exists on object of type 'SomeControl', which should have raised your suspicions.
I think everyone finds WPF data binding takes some time to learn and especially to debug, but persevere. Data binding in WPF is really fantastic, and I still get a kick out of knowing how easily it makes the data on my UIs stay up to date.

Categories

Resources