[英]Is it correct to have a dependency property value that depend on another property value in WPF?
我有一個包含2個數據的類:
public class Settings
{
EnumType Mode;
float Rate;
}
屬性Rate
的值取決於屬性Mode
的值。 我使用CoerceValue函數更新以確保Rate值始終正確。
該屬性以只讀模式(一種方式)綁定到UI,因為我想在寫入時執行一些其他處理。 因此,我在UI控件上創建了一個事件,以了解Rate屬性何時更改。
在我的窗口中,UI綁定到靜態變量SelectedSettings
。
我的問題如下:
當我更改SelectedSettings的值(使用另一個設置類)時,它執行以下操作,而不是在UI中加載新設置:
Mode
值 SelectedSettings
。 Rate
值(現在不正確)。 我做錯了什么 ? 我對依賴屬性和強制系統的使用是否無效?
編輯 :這里有關我的實際狀態的更多信息
我創建了一個用戶控件來顯示兩個設置選項
public partial class EncodingQualitySliderControl : UserControl
{
public static readonly DependencyProperty BitrateProperty = DependencyProperty.Register(
"Bitrate",
typeof(double),
typeof(EncodingQualitySliderControl),
new FrameworkPropertyMetadata(new PropertyChangedCallback(EncodingQualitySliderControl.OnBitrateValueChanged), new CoerceValueCallback(EncodingQualitySliderControl.CoerceBitrateValue)));
public static readonly DependencyProperty EncodingModeProperty = DependencyProperty.Register(
"EncodingMode",
typeof(EncodingMode),
typeof(EncodingQualitySliderControl),
new PropertyMetadata(new PropertyChangedCallback(EncodingQualitySliderControl.OnEncodingModeValueChanged)));
public event EventHandler<double> BitrateValueChanged;
public EncodingQualitySliderControl()
{
this.InitializeComponent();
this.CoerceValue(EncodingQualitySliderControl.BitrateProperty);
Debug.Assert(this.slider != null);
this.slider.ValueChanged += this.Slider_ValueChanged;
}
public EncodingMode EncodingMode
{
get
{
return (EncodingMode)this.GetValue(EncodingQualitySliderControl.EncodingModeProperty);
}
set
{
this.SetCurrentValue(EncodingQualitySliderControl.EncodingModeProperty, value);
}
}
public double Bitrate
{
get
{
return (double)this.GetValue(EncodingQualitySliderControl.BitrateProperty);
}
set
{
this.SetCurrentValue(EncodingQualitySliderControl.BitrateProperty, this.GetNearestTickValue(value));
}
}
private static void OnBitrateValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
{
EncodingQualitySliderControl encodingQualitySliderControl = sender as EncodingQualitySliderControl;
encodingQualitySliderControl.slider.Value = (double)eventArgs.NewValue;
}
private static object CoerceBitrateValue(DependencyObject sender, object basevalue)
{
EncodingQualitySliderControl encodingQualitySliderControl = sender as EncodingQualitySliderControl;
return encodingQualitySliderControl.GetNearestTickValue((double)basevalue);
}
private static void OnEncodingModeValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
{
EncodingQualitySliderControl encodingQualitySliderControl = sender as EncodingQualitySliderControl;
Slider sliderControl = encodingQualitySliderControl.slider;
// ... Some code that change the user control depending on the new mode.
encodingQualitySliderControl.CoerceValue(EncodingQualitySliderControl.BitrateProperty);
// Send ValueChanged in case of bitrate value change from coerce value.
encodingQualitySliderControl.BitrateValueChanged?.Invoke(encodingQualitySliderControl, encodingQualitySliderControl.Bitrate);
}
private void Slider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
this.SetCurrentValue(EncodingQualitySliderControl.BitrateProperty, e.NewValue);
// Only send the bitrate value changed event if the value change come from the slider.
this.BitrateValueChanged?.Invoke(this, e.NewValue);
}
}
然后我有一個包含我的設置數據的課程:
public class ConversionPreset : INotifyPropertyChanged
{
private EncodingMode mode;
private double bitrate;
public event PropertyChangedEventHandler PropertyChanged;
[XmlAttribute]
public EncodingMode Mode
{
get
{
return this.mode;
}
set
{
this.mode = value;
this.OnPropertyChanged();
}
}
[XmlAttribute]
public double Bitrate
{
get
{
return this.bitrate;
}
set
{
this.bitrate= value;
this.OnPropertyChanged();
}
}
}
然后我在我的設置類和用戶控件之間進行了數據綁定。
<controls:EncodingQualitySliderControl x:Name="EncodingQualitySlider" BitrateValueChanged="EncodingQualitySlider_ValueChanged"
EncodingMode="{Binding SelectedPreset.Mode, ElementName=window, Mode=OneWay}"
Bitrate="{Binding SelectedPreset.Bitrate, ElementName=window, Mode=OneWay}" />
在主窗口中有一些代碼可以應用修改
private void EncodingQualitySlider_ValueChanged(object sender, double bitrateValue)
{
this.SelectedPreset?.Bitrate = bitrateValue;
}
編輯2 :
這是一個重現我的問題的最小項目: 鏈接依賴項屬性測試項目
所需的行為是:當我啟動應用程序時,我想查看預設1(比特率32)。 然后,如果我檢查預設2,我想查看225的比特率值。
非常感謝。
由於示例項目,我終於找到了使我的項目工作的方法。
我沒有完全理解依賴屬性的概念,而是嘗試使用控件觸發的事件來避免依賴屬性。
我只是從事件中刪除所有設置設置值的代碼,然后將屬性綁定設置為“ TwoWay”模式。 我之所以沒有這樣做,是因為我不知道如何直接從綁定中設置設置。 為了使其工作,我使用了(如Peter Duniho所說的,謝謝!)值轉換器(IValueConverter)。
謝謝大家的意見!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.