[英]Refresh binding with converter bound to other property
我目前正在為Windows 10構建WinRT應用,但遇到了一個似乎無法找到答案的問題。
在我的主頁上,我有一個綁定到ViewModel中ObservableCollection的地圖標記的列表。 對於這些標記中的每一個,我都需要根據ViewModel的另一個屬性(我們稱之為PropertySelector)的值,顯示MapMarker類中的Property1或Property2文本。
我發現最好的解決方案是在MapMarker類中創建一個同時包含Property1和Property2的結構,將其綁定到標記的文本字段,然后使用Converter選擇要顯示的結構。
由於您無法將屬性綁定到ConverterParameter,因此我在Converter中實現了DependencyProperty,以使其可以訪問PropertySelector。 DP工作正常,轉換器中的屬性已更新,但標記從未更新。 我明白這是因為我沒有觸發任何實際告訴標記更新的事件,但是我沒有設法通過向PropertySelector設置器添加PropertyChanged(“ MarkerList”)或嘗試以編程方式刷新綁定來實現當我使用諸如GetBinding(Text).UpdateSource()之類的屬性更改屬性時,這似乎與WPF具有不同的實現。
我這樣做對嗎? 我該怎么做才能強制綁定刷新?
這是我的相關代碼:
MainPage.xaml中
<Page.Resources>
<local:PropertySelectorConverter x:Key="propertySelectorConverter"
PropertySelector="{Binding PropertySelector}" />
</Page.Resources>
...
<Maps:MapControl>
<Maps:MapItemsControl ItemsSource="{Binding MarkerList}">
<Maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Properties, Converter={StaticResource propertySelectorConverter}}" />
</DataTemplate>
</Maps:MapItemsControl.ItemTemplate>
</Maps:MapItemsControl>
</Maps:MapControl>
<Button Text="Switch Data" Click="SwitchButton_Click" />
MainPage.xaml.cs中
public void SwitchButton_Click(object sender, EventArgs e)
{
viewModel.PropertySelector= !viewModel.PropertySelector
}
ViewModel.cs
class ViewModel : INotifyPropertyChanged
{
private ObservableCollection<Marker> markerList = new ObservableCollection<Marker>();
public ObservableCollection<Marker> MarkerList
{
get { return markerList; }
set { markerList = value; OnPropertyChanged("MarkerList"); }
}
private bool propertySelector = false;
public bool PropertySelector
{
get { return propertySelector; }
set { propertySelector = value; OnPropertyChanged("PropertySelector"); }
}
}
Marker.cs
public class Marker
{
public Tuple<double, double> Properties { get; set; } = Tuple.Create(10, 7);
}
Converter.cs
public class PropertySelectorConverter : DependencyObject, IValueConverter
{
public bool PropertySelector
{
get { return (bool)GetValue(PropertySelectorProperty); }
set { SetValue(PropertySelectorProperty, value); }
}
public static readonly DependencyProperty PropertySelectorProperty =
DependencyProperty.Register("PropertySelector", typeof(bool), typeof(PropertySelectorConverter), new PropertyMetadata(null, CurrentItemChangedCallback));
private static void CurrentItemChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
{
}
public object Convert(object value, Type targetType, object parameter, string language)
{
var properties = (Tuple<double, double>)value;
return PropertySelector ? properties.Item1 : properties.Item2;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}
}
感謝您的時間。
缺少一個很好的, 最小的 , 完整的代碼示例來清楚地說明您的問題,很難甚至不可能提供具體的建議。 但是有一些普遍的想法可以分享……
首先,以我的經驗, ConverterParameter
對於提供給轉換器的靜態(即編譯時)信息更有用。 例如,當您編寫了一個通用轉換器時,該轉換器需要給定綁定的一些特定數據,但是該數據值在編譯時是已知的。
在您的方案中,實際上,轉換器的多個輸入值在運行時會有所不同。 對於這種情況,恕我直言,使用MultiBinding
更合適。 這使您可以提供兩個或多個綁定源,如果其中任何一個源發生更改,WPF都會重新計算綁定值。 不幸的是,這是WPF功能,並且與許多非常有用的WPF功能一樣,Windows Store / Winrt API中已將其省略。
但是,您可以構造一個簡單的中間視圖模型類來實現相同的目的。 例如:
class MultiBindingViewModel : DependencyObject
{
public static readonly DependencyProperty PropertiesProperty = DependencyProperty.Register(
"Properties", typeof(Tuple<double, double>), typeof(MultiBindingViewModel), new PropertyMetadata(null, OnPropertyChanged);
public static readonly DependencyProperty PropertySelectorProperty = DependencyProperty.Register(
"PropertySelector", typeof(bool), typeof(MultiBindingViewModel), new PropertyMetadata(null, OnPropertyChanged);
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
"Value", typeof(double), typeof(MultiBindingViewModel), null);
public Tuple<double, double> Properties
{
get { return (Tuple<double, double>)GetValue(PropertiesProperty); }
set { SetValue(PropertiesProperty, value); }
}
public bool PropertySelector
{
get { return (bool)GetValue(PropertySelectorProperty); }
set { SetValue(PropertySelectorProperty, value); }
}
public double Value
{
get { return (double)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MultiBindingViewModel model = (MultiBindingViewModel)d;
model.Value = model.PropertySelector ? model.Properties.Item1 : model.Properties.Item2;
}
}
然后在您的XAML中使用它,例如:
<TextBlock>
<TextBlock.Text>
<Binding Path="Value">
<Binding.Source>
<local:MultiBindingViewModel Properties="{Binding Properties}"
PropertySelector="{Binding PropertySelector}/>
</Binding.Source>
</Binding>
</TextBlock.Text>
</TextBlock>
注意:缺少完整的代碼示例,以上只是瀏覽器編寫的代碼。 可能存在語法錯誤,或者甚至可能遺漏了Windows Store所需的一些關鍵代碼。 當然,確切的綁定源,路徑和XML名稱空間可能需要進行一些調整,因為我無法確定您如何設置數據上下文等。
但希望上面的內容足夠清楚地顯示了可以在項目中使用的基本方法。
為了完整MultiBinding
,使用MultiBinding
的WPF方法如下所示:
MultiBinding
將始終具有一個實現IMultiValueConverter
的轉換器。 的Convert()
該接口的方法看起來像的IValueConverter
,不同之處在於代替object value
參數允許一個輸入值進行轉換,它具有object[] values
參數。
根據您提供的代碼,我希望您的轉換器看起來像這樣:
public class PropertySelectorConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, string language)
{
var properties = (Tuple<double, double>)values[0];
bool propertySelector = (bool)values[1];
return propertySelector ? properties.Item1 : properties.Item2;
}
public object ConvertBack(object[] values, Type targetType, object parameter, string language)
{
throw new NotSupportedException();
}
}
然后在您的XAML中,您將執行以下操作:
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource propertySelectorConverter}">
<Binding Source="." Path="Properties"/>
<Binding Source="." Path="PropertySelector"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.