Binding to static property

后端 未结 12 2152
夕颜
夕颜 2020-11-22 05:14

I\'m having a hard time binding a simple static string property to a TextBox.

Here\'s the class with the static property:



        
相关标签:
12条回答
  • 2020-11-22 05:36

    You can't bind to a static like that. There's no way for the binding infrastructure to get notified of updates since there's no DependencyObject (or object instance that implement INotifyPropertyChanged) involved.

    If that value doesn't change, just ditch the binding and use x:Static directly inside the Text property. Define app below to be the namespace (and assembly) location of the VersionManager class.

    <TextBox Text="{x:Static app:VersionManager.FilterString}" />
    

    If the value does change, I'd suggest creating a singleton to contain the value and bind to that.

    An example of the singleton:

    public class VersionManager : DependencyObject {
        public static readonly DependencyProperty FilterStringProperty =
            DependencyProperty.Register( "FilterString", typeof( string ),
            typeof( VersionManager ), new UIPropertyMetadata( "no version!" ) );
        public string FilterString {
            get { return (string) GetValue( FilterStringProperty ); }
            set { SetValue( FilterStringProperty, value ); }
        }
    
        public static VersionManager Instance { get; private set; }
    
        static VersionManager() {
            Instance = new VersionManager();
        }
    }
    
    <TextBox Text="{Binding Source={x:Static local:VersionManager.Instance},
                            Path=FilterString}"/>
    
    0 讨论(0)
  • 2020-11-22 05:39

    In .NET 4.5 it's possible to bind to static properties, read more

    You can use static properties as the source of a data binding. The data binding engine recognizes when the property's value changes if a static event is raised. For example, if the class SomeClass defines a static property called MyProperty, SomeClass can define a static event that is raised when the value of MyProperty changes. The static event can use either of the following signatures:

    public static event EventHandler MyPropertyChanged; 
    public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged; 
    

    Note that in the first case, the class exposes a static event named PropertyNameChanged that passes EventArgs to the event handler. In the second case, the class exposes a static event named StaticPropertyChanged that passes PropertyChangedEventArgs to the event handler. A class that implements the static property can choose to raise property-change notifications using either method.

    0 讨论(0)
  • 2020-11-22 05:39

    These answers are all good if you want to follow good conventions but the OP wanted something simple, which is what I wanted too instead of dealing with GUI design patterns. If all you want to do is have a string in a basic GUI app you can update ad-hoc without anything fancy, you can just access it directly in your C# source.

    Let's say you've got a really basic WPF app MainWindow XAML like this,

    <Window x:Class="MyWPFApp.MainWindow"
                xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
                xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                xmlns:local="clr-namespace:MyWPFApp"
                mc:Ignorable="d"
                Title="MainWindow"
                Height="200"
                Width="400"
                Background="White" >
        <Grid>
            <TextBlock x:Name="textBlock"                   
                           Text=".."
                           HorizontalAlignment="Center"
                           VerticalAlignment="Top"
                           FontWeight="Bold"
                           FontFamily="Helvetica"
                           FontSize="16"
                           Foreground="Blue" Margin="0,10,0,0"
                 />
            <Button x:Name="Find_Kilroy"
                        Content="Poke Kilroy"
                        Click="Button_Click_Poke_Kilroy"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        FontFamily="Helvetica"
                        FontWeight="Bold"
                        FontSize="14"
                        Width="280"
                />
        </Grid>
    </Window>
    

    That will look something like this:

    In your MainWindow XAML's source, you could have something like this where all we're doing in changing the value directly via textBlock.Text's get/set functionality:

    using System.Windows;
    
    namespace MyWPFApp
    {
        public partial class MainWindow : Window
        {
            public MainWindow() { InitializeComponent(); }
    
            private void Button_Click_Poke_Kilroy(object sender, RoutedEventArgs e)
            {
                textBlock.Text = "              \\|||/\r\n" +
                                 "              (o o) \r\n" +
                                 "----ooO- (_) -Ooo----";
            }
        }
    }
    

    Then when you trigger that click event by clicking the button, voila! Kilroy appears :)

    0 讨论(0)
  • 2020-11-22 05:45

    Leanest answer (.net 4.5 and later):

        static public event EventHandler FilterStringChanged;
        static string _filterString;
        static public string FilterString
        {
            get { return _filterString; }
            set
            {
                _filterString= value;
                FilterStringChanged?.Invoke(null, EventArgs.Empty);
            }
        }
    

    and XAML:

        <TextBox Text="{Binding Path=(local:VersionManager.FilterString)}"/>
    

    Don't neglect the brackets

    0 讨论(0)
  • 2020-11-22 05:50

    As of WPF 4.5 you can bind directly to static properties and have the binding automatically update when your property is changed. You do need to manually wire up a change event to trigger the binding updates.

    public class VersionManager
    {
        private static String _filterString;        
    
        /// <summary>
        /// A static property which you'd like to bind to
        /// </summary>
        public static String FilterString
        {
            get
            {
                return _filterString;
            }
    
            set
            {
                _filterString = value;
    
                // Raise a change event
                OnFilterStringChanged(EventArgs.Empty);
            }
        }
    
        // Declare a static event representing changes to your static property
        public static event EventHandler FilterStringChanged;
    
        // Raise the change event through this static method
        protected static void OnFilterStringChanged(EventArgs e)
        {
            EventHandler handler = FilterStringChanged;
    
            if (handler != null)
            {
                handler(null, e);
            }
        }
    
        static VersionManager()
        {
            // Set up an empty event handler
            FilterStringChanged += (sender, e) => { return; };
        }
    
    }
    

    You can now bind your static property just like any other:

    <TextBox Text="{Binding Path=(local:VersionManager.FilterString)}"/>
    
    0 讨论(0)
  • 2020-11-22 05:56

    If you are using local resources you can refer to them as below:

    <TextBlock Text="{Binding Source={x:Static prop:Resources.PerUnitOfMeasure}}" TextWrapping="Wrap" TextAlignment="Center"/>
    
    0 讨论(0)
提交回复
热议问题