Setting a custom property within a WPF/Silverlight page Setting a custom property within a WPF/Silverlight page wpf wpf

Setting a custom property within a WPF/Silverlight page


You can work with normal property without Dependency property if you create a Base class for your Page.

public class BaseWindow : Window{   public string MyProperty { get; set; }}
<local:BaseWindow x:Class="BaseWindowSample.Window1" x:Name="winImp"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:local="clr-namespace:BaseWindowSample"     MyProperty="myproperty value"    Title="Window1" Height="300" Width="300"></local:BaseWindow>

And it works even though MyProperty is not a Dependency or Attached.


You would need to make it an attachable property as Pavel noted, then you can write something like this

<Page x:Class="JonSkeetTest.SkeetPage"      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:JonSkeetTest="clr-namespace:JonSkeetTest" mc:Ignorable="d"       d:DesignHeight="300" d:DesignWidth="300"       JonSkeetTest:SkeetPage.MyProperty="testar"    Title="SkeetPage">    <Grid>            </Grid></Page>

However, with only this code-behind, you will get this error instead:

The attachable property 'MyProperty'was not found in type 'SkeetPage'.

The attached property'SkeetPage.MyProperty' is not definedon 'Page' or one of its base classes.


Edit

Unfortunately, you have to use Dependency Properties. Here's a working example

Page

<Page x:Class="JonSkeetTest.SkeetPage"      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"       xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:JonSkeetTest="clr-namespace:JonSkeetTest" mc:Ignorable="d"       JonSkeetTest:SkeetPage.MyProperty="Testing.."      d:DesignHeight="300" d:DesignWidth="300"    Title="SkeetPage">       <Grid>        <Button Click="ButtonTest_Pressed"></Button>    </Grid></Page>

Code-behind

using System.Windows;using System.Windows.Controls;namespace JonSkeetTest{    public partial class SkeetPage    {        public SkeetPage()        {            InitializeComponent();        }        public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register(          "MyProperty",          typeof(string),          typeof(Page),          new FrameworkPropertyMetadata(null,              FrameworkPropertyMetadataOptions.AffectsRender          )        );        public static void SetMyProperty(UIElement element, string value)        {            element.SetValue(MyPropertyProperty, value);        }        public static string GetMyProperty(UIElement element)        {            return element.GetValue(MyPropertyProperty).ToString();        }        public string MyProperty        {            get { return GetValue(MyPropertyProperty).ToString(); }            set { SetValue(MyPropertyProperty, value); }        }        private void ButtonTest_Pressed(object sender, RoutedEventArgs e)        {            MessageBox.Show(MyProperty);        }    }}

If you press the button, you will see "Testing..." in a MessageBox.


You could declare your <Page> element to be a <TestPage> element instead:

<YourApp:TestPage   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   xmlns:YourApp="clr-namespace:YourApp"  MyProperty="Hello"></YourApp:TestPage>

That would do the trick, but you lose InitializeComponent() and the standard designer stuff. Design mode still seems to work flawlessly, though, but I haven't extensively tested this.

UPDATE: This compiles and runs, but does not actually set MyProperty. You also lose the ability to bind event handlers in XAML (although there may be a way to restore that which I am unaware of).

UPDATE 2: Working sample from @Fredrik Mörk which sets the property, but does not support binding event handlers in XAML:

Code-behind:

namespace WpfApplication1{    public partial class MainWindow : Window    {        protected override void OnActivated(EventArgs e)        {            this.Title = MyProperty;        }              public string MyProperty { get; set; }    }}

XAML:

<WpfApplication1:MainWindow    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"     xmlns:WpfApplication1="clr-namespace:WpfApplication1"     Title="MainWindow"     Height="350"     Width="525"    MyProperty="My Property Value"> </WpfApplication1:MainWindow>