通知我有一個自定義組合框,在那裏我有在下拉列表框中選擇一個標籤。我需要改變標籤,正如我在第二張圖片中注意到的那樣。但是我只想通過選中複選框來選擇項目。我可以選擇多個項目,因此標籤應該更新爲選定項目的逗號分隔值。如果沒有足夠的空間顯示標籤的全文,則應該有「...」符號表示在組合框中選擇了更多項目。
我通過繼承文本框控件,我做的依賴屬性的回調事件的所有更改創建的自定義標籤。 (檢查自定義文本框代碼)
現在的問題是,在更改視圖模型中的有界屬性時,自定義文本框控件中的回調事件不會觸發(我正在通過將值添加到可觀察集合在檢查事件複選框後面的代碼中,請檢查複選框事件代碼)。
我可以看到,第一次當我在視圖模型的線由斷點在「吸氣劑」的「SelectedFilterResources」部分命中加載默認數據。但我從來沒有在房產的二傳手部分受到打擊。
自定義文本框
自定義文本框具有「CaptionCollectionChanged」回調事件。這是我有全部邏輯來實現我的場景的地方。 「資源項目」這裏是一個類型的模型。
public class ResourceSelectionBoxLable : TextBox
{
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
IsReadOnly = true;
}
public static List<ResourceItem> LocalFilterdResources = new List<ResourceItem>();
#region Dependancy Properties
public static readonly DependencyProperty FilterdResourcesProperty =
DependencyProperty.Register("SelectedFilterdResources",
typeof (ObservableCollection<ResourceItem>),
typeof (ResourceSelectionBoxLable),
new PropertyMetadata(new ObservableCollection<ResourceItem>(),
CaptionCollectionChanged));
public ObservableCollection<ResourceItem> SelectedFilterdResources
{
get
{
return
(ObservableCollection<ResourceItem>) GetValue(FilterdResourcesProperty);
}
set
{
SetValue(FilterdResourcesProperty, value);
LocalFilterdResources = new List<ResourceItem>(SelectedFilterdResources);
}
}
#endregion
private static void CaptionCollectionChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
var resourceSelectionBoxLable = d as ResourceSelectionBoxLable;
if (resourceSelectionBoxLable != null)
{
if (LocalFilterdResources.Count <= 0)
{
resourceSelectionBoxLable.Text = "Resources"
}
else
{
var actualwidthOflable = resourceSelectionBoxLable.ActualWidth;
var newValue = e.NewValue as string;
//Get the Wdith of the Text in Lable
TextBlock txtMeasure = new TextBlock();
txtMeasure.FontSize = resourceSelectionBoxLable.FontSize;
txtMeasure.Text = newValue;
double textwidth = txtMeasure.ActualWidth;
//True if Text reach the Limit
if (textwidth > actualwidthOflable)
{
var appendedString = string.Join(", ",
LocalFilterdResources.Select(item => item.ResourceCaption)
.ToArray());
resourceSelectionBoxLable.Text = appendedString;
}
else
{
if (LocalFilterdResources != null)
{
var morestring = string.Join(", ",
(LocalFilterdResources as IEnumerable<ResourceItem>).Select(item => item.ResourceCaption)
.ToArray());
var subsring = morestring.Substring(0, Convert.ToInt32(actualwidthOflable) - 4);
resourceSelectionBoxLable.Text = subsring + "...";
}
}
}
}
}
}
自定義組合框。
這是我用上面的自定義標籤的控制。這也是一個自定義控件,因此此控件中的大多數屬性和樣式都是自定義的。 「DPItemSlectionBoxTemplate」是一個依賴屬性,我通過添加附加屬性來控制模板使組合框的選擇框。這個控制工作正常,因爲我在我的系統中的其他地方使用這個控件用於不同的目的。
<styles:CommonMultiComboBox
x:Name="Resourcescmb" IsEnabled="{Binding IsResourceComboEnable,Mode=TwoWay}"
IsTabStop="False"
>
<styles:CommonMultiComboBox.ItemDataTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding IsSelect, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Click="CheckBox_Click"
Content="{Binding ResourceCaption}"
Style="{StaticResource CommonCheckBoxStyle}"
Tag ="{Binding}"
Checked="Resource_ToggleButton_OnChecked" />
</DataTemplate>
</styles:CommonMultiComboBox.ItemDataTemplate>
<styles:CommonMultiComboBox.DPItemSlectionBoxTemplate>
<DataTemplate>
<filtersTemplate:ResourceSelectionBoxLable
Padding="0"
Height="15"
FontSize="10"
SelectedFilterdResources="{Binding DataContext.FilterdResources,ElementName=root ,Mode=TwoWay}" />
</DataTemplate>
</styles:CommonMultiComboBox.DPItemSlectionBoxTemplate>
</styles:CommonMultiComboBox>
視圖模型
private ObservableCollection<ResourceItem> _resourceItems;
public ObservableCollection<ResourceItem> FilterdResources
{
get { return _resourceItems; }
set
{
SetOnChanged(value, ref _resourceItems, "FilterdResources");
}
}
觀的構造模式
FilterdResources=new ObservableCollection<ResourceItem>();
「SetOnChanged」是在視圖模型基類,我們有一個方法inotify的性質的實現。
複選框事件
private void Resource_ToggleButton_OnChecked(object sender, RoutedEventArgs e)
{
var senderControl = sender as CheckBox;
if(senderControl==null)
return;
var selectedContent=senderControl.Tag as ResourceItem;
if (selectedContent != null)
{
ViewModel.FilterdResources.Add(selectedContent);
}
}
我可以從後面的代碼通過視圖模型屬性訪問視圖模型。
爲什麼在更改有界值時沒有通知回調事件?我在這裏錯過了什麼嗎?依賴屬性應該適用於雙向綁定,不是嗎?任何人都可以幫我解決這個問題嗎?
在此先感謝。
我注意到有一些問題可能會咬你一天,我想讓你知道:1.你設置「SelectedFilterdResources」的默認值的方式[原文如此]依賴項屬性創建一個意外的單身人士。 2.我會堅持按照慣例命名依賴屬性,就像靜態DP背景一樣。 3.不要將代碼放在DP的setter中,它不會被綁定引擎調用,而是使用propertyChangedCallback。 – Martin
@ Martin.Thanks。 Yap我從Setter中移動代碼來回調event.Can你可以更多地解釋一下SelectedFilterdResources如何無意中創建Singleton? – Thabo
靜態的backingfield只允許靜態的東西(也就是所有的實例都一樣)與它相關聯。因此,作爲默認值創建的收集實例在所有實例中共享,因此是單例。改爲使用構造函數,您可以將新創建的集合實例指定爲DP中的默認值。 – Martin