簡體   English   中英

編寫綁定時,如何提供供Visual Studio XAML設計器使用的自定義屬性名稱列表?

[英]How to provide a list of custom property names for use by the Visual Studio XAML Designer when writing Bindings?

我有一個名為Model<T>的類,該類實現IDynamicObjectProvider並包裝類型為T的對象,將屬性訪問轉發給基礎值,同時添加其他內容(例如, Model<T>實現INotifyPropertyChangedT不實現)。

我將這些Model<T>對象用作WPF中DataContext屬性,本質上是:

public class Person { public string Name { get; set; } }

public class EditPersonViewModel {
    public Model<Person> Person { get; set; }
    public ICommand SavePersonCommand { get; set; }
}
<StackPanel d:DataContext="{d:DesignInstance vm:EditPersonViewModel}">
    <TextBox Text="{Binding Person.Name}" />
    <Button Command="{Binding SavePersonCommand}" /> 
</StackPanel>

WPF綁定引擎成功綁定到Model<Person>動態獲取器和設置器。

現在,當我編寫以Person.開頭的綁定時,我想從XAML設計器中Person類型的屬性中自動完成Person. ,從而需要盡可能少的應用程序代碼; 理想情況下,它可以完全由定義Model<T>的庫提供程序實現。 (我是寫該庫的人,我希望我的客戶能夠盡可能少地使用Model<T>類)。

以下是我知道的工作方式,以及我對它們的反對意見:

  1. 定義一個新類EditPersonViewModelDesign ,該類將鏡像所有EditPersonViewModel屬性,並將其用作設計實例。

     public class EditPersonViewModelDesign { public Person Person { get; set; } public ICommand SavePersonCommand { get; set; } } 
     <StackPanel d:DataContext="{d:DesignInstance vm:EditPersonViewModelDesign}"> <TextBox Text="{Binding Person.Name}" /> <Button Command="{Binding SavePersonCommand}" /> </StackPanel> 

    雖然不需要太多代碼,但除非我要求人們使構建復雜化(無論他們是否僅添加這些類的項目,還是添加構建變量),否則此類仍會在運行時保留在庫中,這一事實與我完全不合身 而且,Design和View模型類更容易分開。

  2. 完善內部元素的數據上下文並對其影響新的設計實例,例如:

     <StackPanel d:DataContext="{d:DesignInstance vm:EditPersonViewModel}"> <TextBox DataContext="{Binding Person}" d:DataContext="{d:DesignInstance m:Person}" Text="{Binding Name}" /> <Button Command="{Binding SavePersonCommand}" /> </StackPanel> 

    盡管該解決方案不需要創建新的類型,但是添加的XAML代碼對我來說非常具有侵入性。

我認為這里實際上沒有令人滿意的解決方案,因為唯一真正的“非解決方法”是對動態綁定目標(即在設計實例的GetMetaObject()返回的DynamicMetaObject上調用GetDynamicMemberNames對IntelliSense的本機支持。的Model<T>所以,我建議一個特征請求 ,首先。

如果我是您的客戶,我將不會花很多精力在所有地方都為IntelliSense支持而定義設計時間綁定。 與記住或查找並鍵入屬性名稱相比,需要更多的思考來指定正確的綁定。

這是一個想法,可能可行。 當然,我還沒有測試過,但是經過一些研究,它可能會帶您到那里。 您似乎知道自己在做什么:

看一下System.ComponentModel靜態DesignerProperties類的IsInDesignTool屬性:

DesignerProperties.IsInDesignTool

A類if DesignMode do this, else do that的辦法,可以在的ViewModels實施,提出在這里 這可能是返回內部模型 (類型T)而不是包裝模型(模型)的方法。 不知道它是否可以帶您到任何地方,但是仔細考慮可能值得。 無論如何,這是一個有趣的功能……

最后一個想法:通過發布代碼段來改善用戶體驗,並想到一種區分設計時間綁定和運行時綁定的直觀方法。 也許像:

public abstract class ViewModelBase<T>
{
    public Model<T> Model { get; }

    // Maybe use compiler directives to throw exception if requested at runtime
    public T DesignModel { get; }
}

創建的代碼段

d:Text="{Binding DesignModel.Name}" Text="{Binding Model.Name}"

不知道,VS代碼段的功能多么強大,因為我正在使用ReSharper,但是使用ReSharper,您會將控件的DP設置為變量$ControlProp$ ,將屬性名稱$PropName$變量。 然后,如果您按Enter鍵,則IntelliSense將在設計時綁定上起作用,並將屬性名稱自動復制到第二個綁定。

您將輸入一些快捷方式pbind ,然后輸入Text ,Enter和N ,這將觸發IntelliSense,選擇Name ,Enter。 完成。 至少會很容易。

底線:對於您的問題,我沒有即插即用的答案,但我的觀點可能會有所啟發...至少我希望如此。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM