2012-02-03 26 views
8

Tôi có kiểu TextBox định dạng một số nếu hộp không tập trung, nhưng để lại số chưa được định dạng mà nó đang được chỉnh sửa.Tôi có thể thay đổi các thuộc tính của một ràng buộc trong một DataTrigger, mà không biết chính bản thân ràng buộc không?

Đây là kiểu tôi muốn cho nhiều Hộp văn bản số, nhưng tất cả đều chứa các kết buộc văn bản khác nhau. Sự khác biệt duy nhất giữa trình thiết lập văn bản thông thường và trình thiết lập văn bản được kích hoạt là trình thiết lập được kích hoạt có StringFormat=N2 trong ràng buộc.

Có cách nào tôi có thể tạo kiểu chung chung, chẳng hạn như chỉ thay đổi thuộc tính StringFormat của liên kết trong DataTrigger?

<TextBox> 
    <TextBox.Style> 
     <Style TargetType="{x:Type TextBox}"> 
       <Setter Property="Text" Value="{Binding SomeValue, StringFormat=N2, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> 
      <Style.Triggers> 
       <Trigger Property="IsKeyboardFocusWithin" Value="True"> 
        <Setter Property="Text" Value="{Binding SomeValue, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" /> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </TextBox.Style> 
</TextBox> 
+0

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

+0

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

Trả lời

0

Tôi tự hỏi nếu bạn có thể có thể có một tài sản gắn liền trên các chỉnh sửa để giữ giá trị được định dạng (chỉ bị ràng buộc để chỉnh sửa giá trị thực sự với một StringFormat được áp dụng), sau đó trong ra bạn kích hoạt tập trung bạn có thể đặt giá trị chỉnh sửa cho thuộc tính này.

Điều này sẽ dẫn đến ràng buộc vòng tròn mặc dù khi chỉnh sửa không có tiêu điểm, không biết WPF phản ứng như thế nào trong các tình huống như vậy.

0

Đáng buồn là điều này (theo hiểu biết của tôi) không thể thực hiện được. Một giải pháp có thể sẽ được lập trình tạo kiểu như vậy khi đang di chuyển, có thể được đóng gói trong một MarkupExtension có đường dẫn làm tham số hàm tạo.

2

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
+0

Tôi muốn rời khỏi phong cách của mình trong XAML nơi tôi có thể dễ dàng truy cập vào nó để thực hiện thay đổi cho nó. Điều này trông giống như một cơn ác mộng để duy trì :) – Rachel

+0

'Đây là phong cách tôi muốn cho nhiều TextBoxes, nhưng tất cả đều chứa các ràng buộc Text khác nhau làm cho nó có vẻ như nó có giá trị C#. Trong mọi trường hợp, liên kết trong câu trả lời của David đề xuất gần như cùng một thuật toán. –

+0

+1 cho phiên bản hoạt động, mặc dù tôi thích Thuộc tính được đính kèm được hiển thị trong liên kết của David vì nó cho phép tôi giữ phần còn lại của phong cách của tôi trong XAML – Rachel

2

tôi nỗ lực để giải quyết việc này đã kết thúc với một điều khiển tùy chỉnh cộng với một đa-ràng buộc, cả hai nơi đề xuất ở trên.

Điều này cho phép tôi sử dụng đánh dấu như thế này:

< CustomTextBox Value = "{Binding Value"} Format = "N2" />

Tôi cố gắng để gửi mã của tôi nhưng tôi tiếp tục nhận được một lỗi về "mã không được định dạng đúng như mã".

Các vấn đề liên quan