如何注册依赖属性,该属性的值是使用另一个依赖属性的值计算的?
因为WPF在运行时绕过了.NET属性包装器,所以不应该在getter和setter中包含逻辑.解决方案通常是使用PropertyChangedCallbacks.但那些被宣布为静态的.
例如,完成这项设计任务的正确方法是什么:
public bool TestBool
{
get { return (bool)GetValue(TestBoolProperty); }
set
{
SetValue(TestBoolProperty, value);
TestDouble = ((value)?(100.0):(200.0)); // HERE IS THE DEPENDENCY
}
}
public static readonly DependencyProperty TestBoolProperty =
DependencyProperty.Register("TestBool", typeof(bool), typeof(ViewModel));
public double TestDouble
{
get { return ((double)GetValue(TestDoubleProperty)); }
set { SetValue(TestDoubleProperty, value); }
}
public static readonly DependencyProperty TestDoubleProperty =
DependencyProperty.Register("TestDouble", typeof(double), typeof(ViewModel));
Run Code Online (Sandbox Code Playgroud)
只要依赖关系不是循环的,是否有适当的方法来实现这一目标?
我正在考虑为我的应用程序编写WPF用户控件.我在我的应用程序中使用MVVM.
用户控件可能需要可以设置为父视图的依赖项属性.当使用MVVM时,想法是父视图最终将在UserControlsDP与父视图的VM 之间创建绑定)
Dependency Properties需要在View类中创建,因为VM不会继承DependencyObject.这意味着在XAML代码中添加代码.
我想知道你是否可以就使用MVVM开发WPF应用程序时如何设计用户控件提出建议......
如何更改继承的依赖项属性的默认值?在我们的例子中,我们创建了一个Control的子类,默认情况下它的Focusable设置为'true'.我们希望我们的子类具有默认值'false'.
我们一直在做的只是在构造函数中将其设置为'false',但如果有人使用ClearValue,它将返回默认值,而不是构造函数中设置的值.
以下是我目前正在做的事情(这是一个带有'Foo'DP的测试控件的例子.)我不是隐藏属性的'新'的粉丝虽然感谢AddOwner,但它确实指出了到同一个共享实例所以我猜它没关系.它看起来像是继承了所有其他元数据值,所以这很好.只是想知道这是否正确?
public class TestControlBase : Control
{
public static readonly DependencyProperty FooProperty = DependencyProperty.Register(
"Foo",
typeof(int),
typeof(TestControlBase),
new FrameworkPropertyMetadata(4) // Original default value
);
public int Foo
{
get { return (int)GetValue(FooProperty); }
set { SetValue(FooProperty, value); }
}
}
public class TestControl : TestControlBase
{
public static readonly new DependencyProperty FooProperty = TestControlBase.FooProperty.AddOwner(
typeof(TestControl),
new FrameworkPropertyMetadata(67) // New default for this subclass
);
}
Run Code Online (Sandbox Code Playgroud)
标记
更新中...
我认为这更好,因为它消除了"新"呼叫.您仍然可以通过基类上的FooProperty访问它,因为它使用了AddOwner.因此,它在技术上是相同的.
public class TestControl : …Run Code Online (Sandbox Code Playgroud) 即使是最基本的例子,我也会疯狂地试图让它工作.我不能为我的生活得到约束力.这是一个不适合我的超级简单示例.我必须做错事.
我的控件库程序集中的自定义控件:
public class TestControl : Control
{
public static readonly DependencyProperty TestPropProperty =
DependencyProperty.Register("TestProp", typeof(string), typeof(TestControl), new UIPropertyMetadata(null));
public string TestProp
{
get { return (string)GetValue(TestPropProperty); }
set { SetValue(TestPropProperty, value); }
}
static TestControl()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TestControl), new FrameworkPropertyMetadata(typeof(TestControl)));
}
}
Run Code Online (Sandbox Code Playgroud)
它的XAML模板:
<Style TargetType="{x:Type local:TestControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TestControl}">
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}">
<StackPanel>
<TextBlock Text="Testing..." />
<Label Content="{Binding TestProp}" Padding="10" />
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Run Code Online (Sandbox Code Playgroud)
这是XAML在wpf窗口中使用控件来引用我的控件库:
<Grid>
<ItemsControl Name="mylist">
<ItemsControl.ItemTemplate>
<DataTemplate> …Run Code Online (Sandbox Code Playgroud) 好的,我知道.这已经被问了一百万次,但我仍然没有得到它.对不起.
任务:实现最简单的依赖属性,可以在xaml中使用:
<uc:MyUserControl1 MyTextProperty="{Binding Text}"/>
Run Code Online (Sandbox Code Playgroud)
我认为这个答案非常接近.为了更好的可读性,我在这里复制了所有代码(主要来自上面的答案).
<UserControl x:Class="Test.UserControls.MyUserControl1"
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"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Grid>
<!-- Text is being bound to outward representative property;
Note the DataContext of the UserControl -->
<TextBox Text="{Binding MyTextProperty}"/>
</Grid>
</UserControl>
Run Code Online (Sandbox Code Playgroud)
和
public partial class MyUserControl1 : UserControl
{
// The dependency property which will be accessible on the UserControl
public static readonly DependencyProperty MyTextPropertyProperty =
DependencyProperty.Register("MyTextProperty", typeof(string), typeof(MyUserControl1), new UIPropertyMetadata(String.Empty));
public string MyTextProperty
{
get { return (string)GetValue(MyTextPropertyProperty); }
set { …Run Code Online (Sandbox Code Playgroud) 网上的多个来源告诉我们,在MVVM视图和视图模型之间的通信/同步应该通过依赖属性进行.如果我理解正确,应该使用双向绑定将视图的依赖项属性绑定到viewmodel的属性.现在,之前已经提出了类似的问题,但没有足够的答案.
在我开始分析这个相当复杂的问题之前,这是我的问题:
如何将自定义视图DependencyProperty与viewmodel的属性同步?
在理想的世界中,您只需将其绑定为:
<UserControl x:Class="MyModule.MyView" MyProperty="{Binding MyProperty}">
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为MyProperty不是其成员UserControl.卫生署!我尝试了不同的方法,但没有一个证明是成功的.
一种解决方案是定义一个基类UserControlEx,具有必要的依赖属性以使上述工作正常.然而,这很快变得非常混乱.还不够好!
通常情况下,我不会在SO上发布错误消息,但在谷歌搜索发现只有一次点击之后,我认为我至少会在这里发现这个错误.
我有一个自定义控件调用Sparkline一个名为Valuestype 的依赖属性unit[].这是我在一个例子中使用它DataTemplate:
<DataTemplate DataType="{x:Type Activity:ActivityHistory}">
<Controls:Sparkline Grid.Column="1" Values="{Binding Path=Values}" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
此代码无法编译.我收到错误消息:
模板部分不支持"PropertyArrayStart"类型的标签.
行/列编号表示Values属性的开头.
这真的让我失望了.在Google上搜索返回了一个结果,其中John_C遇到了完全相同的问题.不幸的是,他的解决方案涉及将控件移动到单独的组件.好吧,我的已经在一个单独的集会.我的猜测是其他东西在起作用.
我从来没有听说过PropertyArrayStart.搜索只返回与XAML序列化相关的几页.有趣的东西,但没有多大帮助.
考虑到这一点,我无法想到框架中具有数组类型的任何依赖属性.这是允许的吗?
我也尝试使用嵌套元素而不是标记扩展名Binding.
<DataTemplate DataType="{x:Type Activity:ActivityHistory}">
<Controls:Sparkline Grid.Column="1">
<Controls:Sparkline.Values>
<Binding Path="Values"/>
</Controls:Sparkline.Values>
</Controls:Sparkline>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
......还是没有运气
欢迎任何想法!
我正在使用MVVM设计模式创建一个WPF应用程序,我正在尝试扩展TabItem控件,以便在用户单击鼠标中键时关闭选项卡.我正在尝试使用InputBindings实现这一点,并且在我尝试在样式中定义它之前它非常有效.我已经了解到,除非使用DependencyProperty附加,否则无法将InputBindings添加到样式中.所以我在这里跟着这个类似的帖子......它几乎可以工作.我可以使用鼠标中键关闭一个选项卡,但它不能在任何其他选项卡上运行(所有选项卡都在运行时添加并继承相同的样式).
所以我需要一些帮助.为什么这只会在第一次工作,而不是之后?显然,我可以创建一个继承自TabItem的自定义控件并使其工作,但我想弄清楚这一点,因为我可以看到它在我的项目中被扩展.我不是DependencyProperties的专家,所以请帮帮我.谢谢!
样式:
<Style TargetType="{x:Type TabItem}">
<Setter Property="w:Attach.InputBindings">
<Setter.Value>
<InputBindingCollection>
<MouseBinding MouseAction="MiddleClick"
Command="{Binding CloseCommand}"/>
</InputBindingCollection>
</Setter.Value>
</Setter>
...
</Style>
Run Code Online (Sandbox Code Playgroud)
类
public class Attach
{
public static readonly DependencyProperty InputBindingsProperty =
DependencyProperty.RegisterAttached("InputBindings", typeof(InputBindingCollection), typeof(Attach),
new FrameworkPropertyMetadata(new InputBindingCollection(),
(sender, e) =>
{
var element = sender as UIElement;
if (element == null) return;
element.InputBindings.Clear();
element.InputBindings.AddRange((InputBindingCollection)e.NewValue);
}));
public static InputBindingCollection GetInputBindings(UIElement element)
{
return (InputBindingCollection)element.GetValue(InputBindingsProperty);
}
public static void SetInputBindings(UIElement element, InputBindingCollection inputBindings)
{
element.SetValue(InputBindingsProperty, inputBindings);
}
}
Run Code Online (Sandbox Code Playgroud) 我有一个绑定到依赖属性的TextBox,我已经实现了一个PropertyChangedCallBack函数,当文本更改时我需要调用textbox.ScrollToEnd()但是我不能因为PropertChanged函数需要是静态的,有没有办法绕过这个?
static FrameworkPropertyMetadata propertyMetaData = new FrameworkPropertyMetadata("MyWindow",
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(TextProperty_PropertyChanged));
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("TextProperty", typeof(string), typeof(OutputPanel),
propertyMetaData);
private void TextProperty_PropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
textbox.ScrollToEnd(); //An object reference is required for the non-static field.
}
public string Text
{
get
{
return this.GetValue(TextProperty) as string;
}
set
{
this.SetValue(TextProperty, value);
//textbox.ScrollToEnd(); // I originally called it here but I think it should be in the property changed function.
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢,
埃蒙·
当页面的datacontext用于其他绑定时,如何绑定到WPF依赖项属性?(简单问题)
wpf ×10
mvvm ×3
.net ×2
c# ×2
xaml ×2
binding ×1
compilation ×1
data-binding ×1
inputbinding ×1
linkage ×1
static ×1
subclass ×1
wpf-controls ×1