我有一個自定義控制元件,它具有可以設定的屬性,這些屬性將影響控制元件處理方式的邏輯。這應該如何在 MVVM 中處理?
目前我一直試圖將 a 傳遞DependencyProperty給 ViewModel。
示例代碼:
CustomControl.xaml
<UserControl x:Name="Root" ...>
<UserControl.DataContext>
<local:CustomControlViewModel SetDefaultValue="{Binding ElementName=Root, Path=SetDefaultValue, Mode=TwoWay}"/>
</UserControl.DataContext>
...
</UserControl>
CustomControl.xaml.cs
...
public static readonly DependencyProperty SetDefaultValueProperty = DependencyProperty
.Register("SetDefaultValue",
typeof(bool),
typeof(CustomControl),
new FrameworkPropertyMetadata(false));
public string SetDefaultValue
{
get { return (string)GetValue(SetDefaultValueProperty ); }
set { SetValue(SetDefaultValueProperty , value); }
}
...
CustomControlViewModel.cs
...
private bool setDefaultValue;
public bool SetDefaultValue
{
get { return setDefaultValue; }
set
{
if (setDefaultValue!= value)
{
setDefaultValue= value;
OnPropertyChanged("SetDefaultValue"); // INotifyPropertyChanged
}
}
}
...
我對這個屬性的目標是能夠設定一個默認值(獲取默認值需要運行業務邏輯)。所以在另一個視圖中,我會像這樣使用這個控制元件:
<local:CustomControl SetDefaultValue="True"/>
uj5u.com熱心網友回復:
(在我回答之前,我想指出您在這里擁有的實際上是一個用戶控制元件,而不是自定義控制元件。這不是我的挑剔;用戶控制元件是從UserControl類派生的東西,它通常具有關聯的 XAML檔案。自定義控制元件只是派生自Control該類并且沒有關聯的 XAML 檔案。自定義控制元件需要您設定為控制元件模板。自定義控制元件可以設定樣式。用戶控制元件不能。)
問題UserControl是,有時我們會假設一種特定DataContext的 , 一種型別創建一個,然后我們將其所有 XAML 系結到該物件型別。這對于不打算在太多地方重復使用的應用程式的大型主頁很有用
但是另一種方法——你已經開始在這里做——是讓我們的用戶控制他們自己的依賴屬性。那么在這種情況下,為什么不完全免除這個控制的需要DataContext呢?這是使用戶控制元件在許多地方真正可重用的第一步。
除非此控制元件很大,否則很有可能在布置其 XAML 時,它可以在幾個屬性中獲取 XAML 需要系結的所有內容。那么為什么不將所有這些屬性都變成依賴屬性并讓控制元件的 XAML 系結到自身呢?
使類成為它自己的 DataContext。在控制元件布局的根 UI 元素上設定該屬性,然后每個 Binding 應該都能正常作業。
為了說明,我已經重命名了你的控制元件類MyUserControl 我已經將你的“SetDefaultValue”屬性重命名為“BoolOption”讓我們假設它需要顯示的只是一個復選框,代表布林值和復選框上的字串標簽。我們可以只用兩個依賴屬性來做到這一點。(實際上,整個控制元件現在只是一個毫無意義的美化CheckBox控制元件,但請忽略它)
MyUserControl.xaml.cs
public static readonly DependencyProperty BoolOptionProperty =
DependencyProperty.Register(nameof(BoolOption),
typeof(bool),
typeof(MyUserControl),
new FrameworkPropertyMetadata(false));
public string BoolOption
{
get { return (string)GetValue(BoolOptionProperty ); }
set { SetValue(BoolOptionProperty , value); }
}
public static readonly DependencyProperty CheckBoxLabelProperty =
DependencyProperty.Register(nameof(CheckBoxLabel),
typeof(string),
typeof(MyUserControl),
new FrameworkPropertyMetadata(string.Empty));
public string CheckBoxLabel
{
get { return (string)GetValue(CheckBoxLabelProperty ); }
set { SetValue(CheckBoxLabelProperty , value); }
}
// Constructor. Here we set the control to be its own UI's DataContext
public MyUserControl()
{
InitializeComponent();
// Make us be the UI's DataContext. Note that I've set the
// x:Name property root Grid in XAML to be "RootUiElement"
RootUiElement.DataContext = this;
}
MyUserControl.xaml
<UserControl x:Class="MyCompany.MyApp.MyUserControl"
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:MyCompany.MyApp.Controls"
x:Name="Root"
d:DesignHeight="450"
d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type local:MyUserControl}}"
mc:Ignorable="d">
<Grid x:Name="RootUiElement">
<CheckBox IsChecked="{Binding BoolOption}"
Content="{Binding CheckBoxLabel"
/>
</Grid>
</UserControl>
最后,無論您當前的 DataContext 是什么,您都可以在任何您想要的地方使用控制元件,就像這樣
<local:MyUserControl BoolOption="True" CheckBoxLabel="Is Option A enabled?"/>
<local:MyUserControl BoolOption="False" CheckBoxLabel="Is Option B?"/>
或者甚至將它系結到您正在使用它的其他 DataContext 上。假設我的當前DataContext是一個具有布爾UserBoolOptionC屬性的視圖模型
<local:MyUserControl BoolOption="{Binding UseBoolOptionC}" "Is Option C enabled?"/>
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/489031.html
