英文:
Can't get binding to work when moving to UserControl
问题
这里是翻译好的部分:
我们有一些想要重用的XAML。在这个示例中,我将它简化成了一个文本框。
```xaml
<TextBlock Text="{Binding MyProperty.Value}"/>
我们想要重用这个组件,所以我将它放在了一个UserControl中。(不确定这是否是正确的方法)请注意,数据绑定仍然是相同的;"{Binding MyProperty.Value}"
<controls:MyControl ControlValue="{Binding MyProperty.Value}"/>
这个组件工作正常,如果我将一个常数(例如"25"
)放在绑定的位置,它会按预期更新。
但它不会响应模型的更改。
为什么原始XAML中可以工作,但在UserControl中不行?我漏掉了什么?
MyControl.xaml
<UserControl
x:Class="Project.UI.Elements.Common.Controls.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Project.UI.Elements.Common.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="25"
d:DesignWidth="100">
<TextBlock Text="{Binding ControlProperty}"/>
</UserControl>
MyControl.xaml.cs
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
// 用户控件项目模板在 https://go.microsoft.com/fwlink/?LinkId=234236 中有文档。
namespace Project.UI.Elements.Common.Controls
{
public sealed partial class MyControl : UserControl
{
public static readonly DependencyProperty ControlValueProperty =
DependencyProperty.Register("ControlValue", typeof(double), typeof(MyControl), new PropertyMetadata(0.0));
public MyControl()
{
this.InitializeComponent();
DataContext = this;
}
public double ControlValue
{
get { return (double)GetValue(ControlValueProperty); }
set { SetValue(ControlValueProperty, value); }
}
}
}
英文:
We had a bit of XAML that we wanted to reuse. In this example, I've reduced it to a textbox.
<TextBlock Text="{Binding MyProperty.Value}"/>
We want to reuse the component, so I put it in a UserControl. (Not sure if this is the right way) Note that the data binding is still the same; "{Binding MyProperty.Value}"
<controls:MyControl ControlValue="{Binding MyProperty.Value}"/>
The component works, in that if I put a constant (e.g. "25"
) instead of the binding, it is updated as expected.
But it doesn't respond to changes in the model.
Why does it work in the original XAML, but not with the UserControl? What am I missing here?
MyControl.xaml
<UserControl
x:Class="Project.UI.Elements.Common.Controls.MyControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Project.UI.Elements.Common.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="25"
d:DesignWidth="100">
<TextBlock Text="{Binding ControlProperty}"/>
</UserControl>
MyControl.xaml.cs
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
// The User Control item template is documented at https://go.microsoft.com/fwlink/?LinkId=234236
namespace Project.UI.Elements.Common.Controls
{
public sealed partial class MyControl : UserControl
{
public static readonly DependencyProperty ControlValueProperty =
DependencyProperty.Register("ControlValue", typeof(double), typeof(MyControl), new PropertyMetadata(0.0));
public MyControl()
{
this.InitializeComponent();
DataContext = this;
}
public double ControlValue
{
get { return (double)GetValue(ControlValue); }
set { SetValue(ControlValue, value); }
}
}
}
答案1
得分: 1
根据您提供的当前场景,建议在UserControl中使用**{x:bind}**。
MainPage.xaml
<TextBlock Text="{Binding MainPageControlValue, Mode=OneWay}"/>
<local:MyControl ControlValue="{Binding MainPageControlValue, Mode=OneWay}"/>
MainPage.xaml.cs
public static readonly DependencyProperty MainPageValueProperty =
DependencyProperty.Register("MainPageControlValue", typeof(string), typeof(MainPage), new PropertyMetadata("default"));
public MainPage()
{
this.InitializeComponent();
this.DataContext = this;
}
public string MainPageControlValue
{
get { return (string)GetValue(MainPageValueProperty); }
set { SetValue(MainPageValueProperty, value); }
}
MyControl.xaml
<Grid>
<TextBlock Text="{x:Bind ControlValue, Mode=OneWay}"/>
</Grid>
MyControl.xaml.cs
public sealed partial class MyControl : UserControl
{
public static readonly DependencyProperty ControlValueProperty =
DependencyProperty.Register("ControlValue", typeof(string), typeof(MyControl), new PropertyMetadata("default"));
public MyControl()
{
this.InitializeComponent();
}
public MyViewModel VM { get; set; }
public string ControlValue
{
get { return (string)GetValue(ControlValueProperty); }
set { SetValue(ControlValueProperty, value); }
}
}
在尝试使用x:bind时,请不要在UserControl中使用DataContext = this
,否则将会出现以下绑定错误。
MainPageControlValue UserControlTest.MyControl.ControlValue, Name='myControl' String BindingExpression path error: 'MainPageControlValue' property not found on 'UserControlTest.MyControl'.
对于x:bind,DataContext是当前页面,它将在当前Code-Behind类中查找属性。但是对于Binding,默认情况下,它假定您正在绑定到标记页的DataContext。
如果您需要使用Binding,建议使用自定义控件。您可以参考这个线程。
顺便说一下,在Visual Studio中调试时,有XAML Binding Failures Window和APP的顶部提示。
英文:
According to the current scenario you provided, it is recommended to use {x:bind} in UserControl.
MainPage.xaml
<TextBlock Text="{Binding MainPageControlValue, Mode=OneWay}"/>
<local:MyControl ControlValue="{Binding MainPageControlValue, Mode=OneWay}"/>
MainPage.xaml.cs
public static readonly DependencyProperty MainPageValueProperty =
DependencyProperty.Register("MainPageControlValue", typeof(string), typeof(MainPage), new PropertyMetadata("default"));
public MainPage()
{
this.InitializeComponent();
this.DataContext = this;
}
public string MainPageControlValue
{
get { return (string)GetValue(MainPageValueProperty); }
set { SetValue(MainPageValueProperty, value); }
}
MyControl.xaml
<Grid>
<TextBlock Text="{x:Bind ControlValue, Mode=OneWay}"/>
</Grid>
MyControl.xaml.cs
public sealed partial class MyControl : UserControl
{
public static readonly DependencyProperty ControlValueProperty =
DependencyProperty.Register("ControlValue", typeof(string), typeof(MyControl), new PropertyMetadata("default"));
public MyControl()
{
this.InitializeComponent();
}
public MyViewModel VM { get; set; }
public string ControlValue
{
get { return (string)GetValue(ControlValueProperty); }
set { SetValue(ControlValueProperty, value); }
}
}
Please don't use DataContext = this
in UserControl When you try to use x:bind, otherwise you will get the following binding error.
> MainPageControlValue UserControlTest.MyControl.ControlValue,
> Name='myControl' String BindingExpression path error:
> 'MainPageControlValue' property not found on
> 'UserControlTest.MyControl'
For x:bind, the DataContext is current page, it will find the property in the current Code-Bebind class. But for Binding, assumes, by default, that you're binding to the DataContext of your markup page.
If you need to use Binding, it is recommended that you use Custom Control. You can refer to this thread.
By the way, there are XAML Binding Failures Window in Visual Studio and Top tips on APP when debugging.
答案2
得分: 0
在BatteryLevelControl
类中,您将数据上下文设置为this。但是,由于该类是从UserControl
派生的,因此不支持INotifyPropertyChanged
,因此不会接收到任何更改。尝试将数据上下文设置为您从INotifyPropertyChanged
派生的类,该类包含您的依赖属性。
英文:
in the BatteryLevelControl
class, you set the data context to this. However, since the class is derived from UserControl
, it does not support the INotifyPropertyChanged
and thus does not receive any changes. Try setting the data context to your class that was derived from INotifyPropertyChanged
and that contains your dependency properties.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论