如何更改继承的依赖项属性的默认值?在我们的例子中,我们创建了一个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) 如何以编程方式向datatemplates添加控件?
例如.下面我创建了TextBlock和DataTemplate.
TextBlock text = new TextBlock();
DataTemplate template = new DataTemplate();
Run Code Online (Sandbox Code Playgroud)
现在我需要将TextBlock添加到DataTemplate.怎么做到这一点?
我知道后面的代码中还有其他addind数据模板的方法1.在XAML中创建数据模板并将其加载到后面的代码上2.使用XamlParser创建和添加
但我需要按照我在示例中展示的方式来做.
需要一些帮助.
我们正在控制子类中进行自定义绘制OnRender
.此绘图代码基于外部触发器和数据.因此,每当触发器触发时,我们都需要根据该数据重新呈现控件.我们要做的是找出如何强制控件重新渲染但不经过整个布局传递.
如上所述,我所看到的大多数答案都围绕着使Visual
无效的布局无效,这会迫使新的测量并安排非常昂贵的通行证,特别是对于像我们这样非常复杂的视觉树.但同样,布局不会改变,VisualTree 也不会改变.唯一能做的就是外部数据的呈现方式不同.因此,这严格来说是纯粹的渲染问题.
同样,我们只是在寻找一种简单的方法来告诉控件它需要重新执行OnRender
.我见过一个"黑客"在您创建一个新的DependencyProperty
,并用你刚才设置的时候要刷新的控制一定的价值"AffectsRender"注册它,但我更感兴趣的是发生了什么事情的默认实现内那些属性:他们所谓的影响那种行为.
好了,它看起来像没有任何这样的呼叫,因为即使是AffectsRender
国旗还是引起内部安排通(按照以下CodeNaked的答案),但我已经张贴,显示了内置行为,以及一个工作-第二个答案周围禁止你的布局传递代码从一个简单的可空大小作为标志运行.见下文.
我们正在创建一个对象层次结构,其中每个项目都有一个其他项目的集合,每个项目也有一个Parent
指向其父项目的属性.很标准的东西.我们还有一个ItemsCollection
继承自的类,该类Collection<Item>
本身具有Owner
指向集合所属项的属性.再一次,没有什么有趣的.
当一个项目被添加到ItemsCollection
类中时,我们希望它自动设置Item的父项(使用集合的Owner
属性),当项目被删除时,我们想要清除父项.
这就是事情.我们只希望Parent
设置器可用ItemsCollection
,没有别的.这样,我们不仅可以知道项目的父项是谁,还可以通过检查现有值Parent
,或者让某人随意将其更改为其他项目来确保项目不会添加到多个集合中.
我们知道如何做到的两种方式是:
将setter标记为private,然后将集合定义包含在项目本身的范围内.亲:全面保护.Con:嵌套类的丑陋代码.
ISetParent
在仅ItemsCollection
知道的Item上使用私有接口.亲:更清晰的代码,易于遵循.Con:从技术上讲,任何了解界面的人都可以投射Item
并获得制定者.
现在技术上通过反思任何人都可以得到任何东西,但仍然......试图找到最好的方法来做到这一点.
现在我知道有C++中的功能,称为Friend
什么,让你在一个类中指定的,否则私有成员为可用于另一这将是很好的方案,但我不知道在C#中的任何这样的事情.
在伪代码中(例如,所有属性都更改了通知,为了简洁而删除了这些通知,我只是在这里输入,而不是从代码中复制),我们有...
public class Item
{
public string Name{ get; set; }
public Item Parent{ get; private set; }
public ItemsCollection ChildItems;
public Item()
{
this.ChildItems = new ItemsCollection (this);
}
}
public class ItemsCollection : ObservableCollection<Item>
{
public ItemsCollection(Item owner)
{
this.Owner = owner;
}
public Item …
Run Code Online (Sandbox Code Playgroud) 我在itemscontrol中使用自定义模板来显示以下结果:
item 1, item 2, item3,
Run Code Online (Sandbox Code Playgroud)
我想更改最后一项的模板,结果变为:
item 1, item2, item3
Run Code Online (Sandbox Code Playgroud)
ItemsControl:
<ItemsControl ItemsSource="{Binding Path=MyCollection}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" IsItemsHost="True"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}"/>
<TextBlock Text=", "/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)
有没有人可以为我的问题提供解决方案?谢谢!
我想TextEditor
在我的 ForEach 中有一些,我在 down 中制作了这个示例代码!正如您在 Image 中看到的代码和结果,它TextEditor
就像一个贪婪的视图,并占用所有可用空间!至少对我来说有很多缺点!
如果我将高度限制为自定义值,那么我将失去查看 TextEditor 本身的所有字符串和字符串行的可能性,并且我必须向上或向下滚动才能看到其他行,这不是我的设计!
我的目标是占用TextEditor
所需的空间,如果我输入新的字符串行,那么它的高度可以增加,或者如果我删除字符串行,它的高度可以缩小到至少 1 行!
我想知道我该怎么做?
struct ContentView: View {
@StateObject var textEditorReferenceType: TextEditorReferenceType = TextEditorReferenceType()
var body: some View {
Text("TextEditorView").bold().padding()
VStack {
ForEach(textEditorReferenceType.arrayOfString.indices, id: \.self, content: { index in
TextEditorView(string: $textEditorReferenceType.arrayOfString[index])
})
}
.padding()
}
}
struct TextEditorView: View {
@Binding var string: String
var body: some View {
TextEditor(text: $string)
.cornerRadius(10.0)
.shadow(radius: 1.0)
}
}
class TextEditorReferenceType: ObservableObject {
@Published var arrayOfString: [String] …
Run Code Online (Sandbox Code Playgroud) 由于此问题在这里,我想编写处理,你继承列表或集合,然后额外的属性,将其添加的情况下自定义JsonConverter.因此,一种方法是忽略所有基类属性,并仅序列化已定义类中的属性.(从技术上讲这不会起作用,因为如果你继承了那个子类,你就会破坏序列化,但它确实让我想知道......)
是否有可能通过反射(我知道答案是肯定的,因为Reflector正是如此,但我不知道如何)只获得在类本身定义的成员而不是继承的成员?例如...
public class MyBaseClass
{
public string BaseProp1 { get; set; }
public string BaseProp2 { get; set; }
}
public class MySubClass : MyBaseClass
{
public string SubProp1 { get; set; }
public string SubProp2 { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我想反映的MySubClass
,只有获得SubProp1
和SubProp2
而忽略BaseProp1
和BaseProp2
.所以,可以说是如何做呢?
中号
当我CGColorGetComponents
用CGColor
a返回时UIColor
,它似乎正常工作,除了白色和黑色.
这是代码......
CGColorRef myColorRef = [[UIColor whiteColor] CGColor];
const CGFloat * colorComponents = CGColorGetComponents(myColorRef);
NSLog(@"r=%f, g=%f, b=%f, a=%f",
colorComponents[0],
colorComponents[1],
colorComponents[2],
colorComponents[3]);
Run Code Online (Sandbox Code Playgroud)
这个日志
r=1.000000, g=1.000000, b=0.000000, a=0.000000
Run Code Online (Sandbox Code Playgroud)
注意B和A都是零,而不是一个.
如果你替换其他颜色,如redColor,blueColor等,它可以工作...... RGB和A值设置为人们所期望的.但同样,黑色和白色产生奇怪的结果.这个功能有问题,还是我应该做一些解决方法/任务?
正如标记的答案所示,Reflector确认UserControl会覆盖一些方法,因此虽然两者之间的界面完全相同,并且您可以使用VS设计器,但行为上存在细微差别.我会让读者更多地研究这些差异,但这里是子类代码......
public class UserControl : ContentControl
{
// Fields
private static DependencyObjectType _dType;
// Methods
static UserControl()
{
FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(
typeof(UserControl),
new FrameworkPropertyMetadata(typeof(UserControl)));
_dType = DependencyObjectType.FromSystemTypeInternal(
typeof(UserControl));
UIElement.FocusableProperty.OverrideMetadata(
typeof(UserControl),
new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));
KeyboardNavigation.IsTabStopProperty.OverrideMetadata(
typeof(UserControl),
new FrameworkPropertyMetadata(BooleanBoxes.FalseBox));
Control.HorizontalContentAlignmentProperty.OverrideMetadata(
typeof(UserControl),
new FrameworkPropertyMetadata(HorizontalAlignment.Stretch));
Control.VerticalContentAlignmentProperty.OverrideMetadata(
typeof(UserControl),
new FrameworkPropertyMetadata(VerticalAlignment.Stretch));
}
internal override void AdjustBranchSource(RoutedEventArgs e)
{
e.Source = this;
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new UserControlAutomationPeer(this);
}
// Properties
internal override DependencyObjectType DTypeThemeStyleKey
{
[TargetedPatchingOptOut("Performance critical to inline this type of method across NGen …
Run Code Online (Sandbox Code Playgroud) 我希望我的类有一个可以分配不可变数组的存储属性.如果我这样做:
class MyClass{
var myItems:[String]
}
Run Code Online (Sandbox Code Playgroud)
我可以为我的属性分配不同的数组,但数组将是可变的.如果我这样做:
class MyClass{
let myItems:[String]
}
Run Code Online (Sandbox Code Playgroud)
我的数组是不可变的,但我不能改变分配给它的内容.有没有办法让我的蛋糕也不会改变它?
我提出的最好的方法是在数组周围创建一个包装器,然后使用该类型作为属性,如下所示:
class MyClass{
struct ImmutableWrapper{
let array:[String]
}
var myItems:ImmutableWrapper
}
Run Code Online (Sandbox Code Playgroud)
......这不是很优雅.
wpf ×4
c# ×3
subclass ×3
swift ×2
arrays ×1
base-class ×1
code-behind ×1
datatemplate ×1
dynamic ×1
friend ×1
immutability ×1
invalidation ×1
ios ×1
iphone ×1
itemscontrol ×1
objective-c ×1
onrender ×1
parent-child ×1
private ×1
redraw ×1
reflection ×1
swiftui ×1
templates ×1
uicolor ×1