Setting a custom property within a WPF/Silverlight page

后端 未结 10 1214
萌比男神i
萌比男神i 2020-12-14 15:10

This sounds like it should be simple. I have a Page declared in XAML in the normal way (i.e. with "Add new item...") and it has a custom property. I\'

相关标签:
10条回答
  • 2020-12-14 15:35

    I just tried to do the same with some different intent, though.

    The real answer actually is: You need the WPF convention for Set-methods done right. As outlined here: http://msdn.microsoft.com/en-us/library/ms749011.aspx#custom you have to define the SetXxx and GetXxx methods if you are about to definde an attached property named Xxx.

    So see this working example:

    public class Lokalisierer : DependencyObject
    {
        public Lokalisierer()
        {
        }
    
        public static readonly DependencyProperty LIdProperty = 
            DependencyProperty.RegisterAttached("LId", 
                                                typeof(string), 
                                                typeof(Lokalisierer),
                                                new FrameworkPropertyMetadata( 
                                                      null,
                                                         FrameworkPropertyMetadataOptions.AffectsRender | 
                                                         FrameworkPropertyMetadataOptions.AffectsMeasure,
                                                         new PropertyChangedCallback(OnLocIdChanged)));
    
        private static void OnLocIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
        // on startup youll be called here
        }
    
        public static void SetLId(UIElement element, string value)
        {
          element.SetValue(LIdProperty, value);
        }
        public static string GetLId(UIElement element)
        {
          return (string)element.GetValue(LIdProperty);
        }
    
    
        public string LId
        {
            get{    return (string)GetValue(LIdProperty);   }
            set{ SetValue(LIdProperty, value); }
        }
    }
    

    And the WPF part:

    <Window x:Class="LokalisierungMitAP.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:me="clr-namespace:LokalisierungMitAP"
    Title="LokalisierungMitAP" Height="300" Width="300"
    >
    <StackPanel>
        <Label  me:Lokalisierer.LId="hhh">Label1</Label>
       </StackPanel>
    

    BTW: You need also to inherit DependencyObject

    0 讨论(0)
  • 2020-12-14 15:35

    You can set the property with a style:

    <Page.Style>
        <Style TargetType="{x:Type wpfSandbox:TestPage}">
            <Setter Property="MyProperty" Value="This works" />
        </Style>
    </Page.Style>
    

    But it only works for dependency properties!

    public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.Register(
        nameof(MyProperty), typeof(string), typeof(Page),
        new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
    
    public string MyProperty
    {
        get { return (string)GetValue(MyPropertyProperty); }
        set { SetValue(MyPropertyProperty, value); }
    }
    
    0 讨论(0)
  • 2020-12-14 15:36

    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>
    
    0 讨论(0)
  • 2020-12-14 15:36

    This worked for me

    <Window x:Class="WpfSandbox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfSandbox"        
        xmlns:src="clr-namespace:WpfSandbox" 
        Title="MainWindow" Height="350" Width="525"
        src:MainWindow.SuperClick="SuperClickEventHandler">
    </Window>
    

    So this may work for the original question (didn't try). Note xmlns:src.

    <Page x:Class="WpfSandbox.TestPage"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:local="clr-namespace:WpfSandbox"        
      xmlns:src="clr-namespace:WpfSandbox" 
      src:TestPage.MyProperty="MyPropertyValue">
    </Page>
    
    0 讨论(0)
提交回复
热议问题