Is có cách nào tôi có thể làm cho phong cách này chung chung, chẳng hạn như chỉ thay đổi tài sản StringFormat của ràng buộc trong DataTrigger?
Kế thừa Style
và XAML mới sẽ trở thành này:
<TextBox>
<TextBox.Style>
<local:FlyingStyle Binding="{Binding ElementName=This, Path=SomeValue}" StringFormat="F2" />
</TextBox.Style>
</TextBox>
Đây là lớp ...
public class FlyingStyle : Style
{
public FlyingStyle()
: base(typeof(TextBox))
{ }
string _stringFormat;
public string StringFormat
{
get { return _stringFormat; }
set
{
_stringFormat = value;
CheckInitialize();
}
}
Binding _binding;
public Binding Binding
{
get { return _binding; }
set
{
_binding = value;
CheckInitialize();
}
}
void CheckInitialize()
{
if (StringFormat == null || Binding == null) { return; }// need both
Setters.Add(CreateSetter(Binding, StringFormat));
var trigger = new Trigger
{
Property = UIElement.IsKeyboardFocusWithinProperty,
Value = true,
};
trigger.Setters.Add(CreateSetter(Binding));
Triggers.Add(trigger);
}
/// <summary>Creates the common <see cref="Setter"/>.</summary>
static Setter CreateSetter(Binding binding, string stringFormat = null)
{
// must create a copy, because same binding ref but diff StringFormats
var bindingCopy = new Binding
{
// these could be copies as well
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
ValidatesOnDataErrors = true,
Mode = BindingMode.TwoWay,
Path = binding.Path,
AsyncState = binding.AsyncState,
BindingGroupName = binding.BindingGroupName,
BindsDirectlyToSource = binding.BindsDirectlyToSource,
Converter = binding.Converter,
ConverterCulture = binding.ConverterCulture,
ConverterParameter = binding.ConverterParameter,
ElementName = binding.ElementName,
FallbackValue = binding.FallbackValue,
IsAsync = binding.IsAsync,
NotifyOnSourceUpdated = binding.NotifyOnSourceUpdated,
NotifyOnTargetUpdated = binding.NotifyOnTargetUpdated,
NotifyOnValidationError = binding.NotifyOnValidationError,
//StringFormat = set below...
TargetNullValue = binding.TargetNullValue,
UpdateSourceExceptionFilter = binding.UpdateSourceExceptionFilter,
ValidatesOnExceptions = binding.ValidatesOnExceptions,
XPath = binding.XPath,
//ValidationRules = binding.ValidationRules
};
// mutex ElementName, so modify if needed
// Source = binding.Source,
// RelativeSource = binding.RelativeSource,
if (stringFormat != null)
{
bindingCopy.StringFormat = stringFormat;
}
return new Setter(TextBox.TextProperty, bindingCopy);
}
}
Lưu ý rằng thử nghiệm của tôi là
- các MainWindow generic
- impl INotifyPropertyChanged
SomeValue
INPC tài sản
- DataContext = này
- x: Name = Đây
Nguồn
2012-02-11 06:13:51
Tôi nghĩ rằng không thể thay đổi bất kỳ thuộc tính nào của một ràng buộc sau khi nó đã được áp dụng. Ít nhất khi tôi cố gắng thay đổi thuộc tính StringFormat của một ràng buộc hiện tại, tôi nhận được một InvalidOperationException nói rằng 'Ràng buộc không thể thay đổi sau khi nó đã được sử dụng.' Với tôi có vẻ như không có cách nào xung quanh việc tạo một ràng buộc mới mỗi khi thay đổi tiêu điểm . – Clemens
Hãy suy nghĩ về điều này một lần nữa, và xem xét một số loại giải pháp thuộc tính 'Dữ liệu' đính kèm, nơi trình xử lý thay đổi thuộc tính sẽ đính kèm các trình xử lý GotFocus/LostFocus, vv Cuối cùng, tôi muốn có một TextBox bắt nguồn với các thuộc tính' Data' và 'StringFormat ', sẽ đặt thuộc tính' Văn bản' theo giá trị của chúng và trạng thái lấy nét hiện tại. – Clemens