WPF UserControl无法在窗体外绑定

时间:2015-11-30 21:44:23

标签: c# wpf binding

我已将其绑定在自身内,但我无法弄清楚表单绑定有什么问题。我正在检查不同的帖子,但我无法得到它(

用户控制XML:

<UserControl x:Class="Lab7_KPZ.Controls.UnitBar"
             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:local="clr-namespace:Lab7_KPZ.Controls"
             mc:Ignorable="d" 
             d:DesignHeight="177" d:DesignWidth="169" DataContext="{Binding RelativeSource={RelativeSource Self}}">
    <Grid>
        <Label x:Name="HPlabel" Content="{Binding _HP, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="0,131,0,0" VerticalAlignment="Top" Height="23" Width="169" Background="#FF35DC5B" HorizontalContentAlignment="Center"/>
        <Label x:Name="MPlabel" Content="{Binding _MP, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="0,154,0,0" VerticalAlignment="Top" Height="23" Width="169" Background="#FF0387E2" HorizontalContentAlignment="Center"/>

    </Grid>
</UserControl>

用户控制CS:

  public partial class UnitBar : UserControl, INotifyPropertyChanged
    {
        private string _hp = "1000 / 1000";
        private string _mp = "400 / 400";
        private string _imgPath;

        public string _HP
        {
            get
            { 
                return (string)GetValue(HitP);
            }
            set
            {

                SetValue(HitP, value);
                OnPropertyChanged("_HP");
            }
        }
        public string _MP
        {
            get
            {
                return _mp;
            }
            set
            {
                _hp = value;
                OnPropertyChanged("_MP");
            }
        } 

        public static readonly DependencyProperty HitP = DependencyProperty.Register("_HP", typeof(string), typeof(UnitBar),
                               new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, EmpNamePropertyChanged));
        static void EmpNamePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            UnitBar x = (UnitBar)sender;
            x._HP = (string)e.NewValue;
        }
        public UnitBar()
        {
            InitializeComponent();
           (this.Content as FrameworkElement).DataContext = this; 
        }

        public event PropertyChangedEventHandler PropertyChanged; 
        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

主窗口xml:

<Window x:Class="Lab7_KPZ.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:Lab7_KPZ"
        xmlns:controls="clr-namespace:Lab7_KPZ.Controls"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid Name="mainGrid"> 
        <controls:UnitBar _HP="{Binding Path=HP, UpdateSourceTrigger=PropertyChanged, Mode=OneWay }"> </controls:UnitBar> 

        <TextBlock x:Name="textBlock" HorizontalAlignment="Left" Margin="10,237,0,0" TextWrapping="Wrap" Text="{Binding Path=HP, UpdateSourceTrigger=PropertyChanged, Mode=OneWay }" VerticalAlignment="Top" Width="52" />
        <Button x:Name="button" Content="Button" HorizontalAlignment="Left" Margin="10,192,0,0" VerticalAlignment="Top" Width="75" Command="{Binding  Path=SaveCommand, UpdateSourceTrigger=PropertyChanged}"/>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="205,20,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120" Text="{Binding Path=HP, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource }"/>

    </Grid>
</Window>

main window cs:
  public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MyView(); 
        } 
    }

我对datacontext的看法:

{
        private string _hp;
        private int _mp;
        private int i = 5;

        public string HP
        {
            get { return _hp; }
            set
            {
                _hp = value;
                OnPropertyChanged("HP");
            }
        }
        public string stringHP
        {
            get { return "100 / 100"; } 
        }
        public int MP
        {
            get { return _mp; }
            set {
                _mp++;
                OnPropertyChanged("MP");
                }
        }

        private ICommand _saveCommand;

        public ICommand SaveCommand
        {
            get
            {
                if (_saveCommand == null)
                {
                    _saveCommand = new RelayCommand(
                        param => this.SaveObject(),
                        param => this.CanSave()
                    );
                }
                return _saveCommand;
            }
        }

        private bool CanSave()
        {
            // Verify command can be executed here
            return true;
        } 
        private void SaveObject()
        {
            // Save command execution logic 
        } 


        public event PropertyChangedEventHandler PropertyChanged;

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

1 个答案:

答案 0 :(得分:1)

您的代码存在一些问题。

a)如果要从控件外部绑定DataContext,则不应将UserControl设置为自身UserControl。从DataContext="{Binding RelativeSource={RelativeSource Self}}"声明RelativeSource Binding

中删除此内容

b)使用UserControl内的<Grid> <Label x:Name="HPlabel" Content="{Binding _HP, RelativeSource={RelativeSource AncestorType={local:UnitBar}}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="0,131,0,0" VerticalAlignment="Top" Height="23" Width="169" Background="#FF35DC5B" HorizontalContentAlignment="Center" /> <Label x:Name="MPlabel" Content="{Binding _MP, RelativeSource={RelativeSource AncestorType={local:UnitBar}}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" Margin="0,154,0,0" VerticalAlignment="Top" Height="23" Width="169" Background="#FF0387E2" HorizontalContentAlignment="Center" /> </Grid> 数据绑定到自己的属性:

UserControl

这将使您能够从控件外部绑定到DependencyProperty

c)正确定义public static readonly DependencyProperty AquariumGraphicProperty = DependencyProperty.Register( "AquariumGraphic", typeof(Uri), typeof(AquariumObject), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, new PropertyChangedCallback(OnUriChanged) ) ); public Uri AquariumGraphic { get { return (Uri)GetValue(AquariumGraphicProperty); } set { SetValue(AquariumGraphicProperty, value); } } (示例来自MSDN上的Custom Dependency Properties页面):

DependencyProperty

请注意命名约定... CLR属性获取正常的属性名称,DependencyProperty获取相同的名称,但使用&#39;属性&#39;附在最后。在其中一个属性的名称中使用下划线非常罕见。在您的情况下,您的public static readonly DependencyProperty HitProperty = DependencyProperty.Register( "Hit", typeof(string), typeof(UnitBar), new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, EmpNamePropertyChanged) ); public string Hit { get { return (string)GetValue(HitProperty); } set { SetValue(HitProperty, value); } } 之一看起来像这样:

<Label x:Name="HPlabel" Content="{Binding Hit, RelativeSource={RelativeSource 
    AncestorType={local:UnitBar}}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" 
    HorizontalAlignment="Left" Margin="0,131,0,0" VerticalAlignment="Top" Height="23" 
    Width="169" Background="#FF35DC5B" HorizontalContentAlignment="Center" />

在XAML中,我们使用CLR属性的名称将数据绑定到...在这种情况下,上面的代码将成为:

<table class="data-table"....>