سؤال

باستخدام DataGrid WPF ، أحتاج إلى تغيير العديد من الخصائص ذات الصلة وخصائص DataGridCell - مثل المقدمة ، fontstyle ، isenabled وما إلى ذلك - بناءً على القيمة ذات الصلة لخاصية كائن الخلية.

الآن من السهل القيام بذلك في التعليمات البرمجية ، على سبيل المثال (باستخدام مجموعة يمكن ملاحظتها من عمليات المراقبة):

  var b = new Binding("IsLocked") { Source = row[column], Converter = new BoolToFontStyleConverter() };
  cell.SetBinding(Control.FontStyleProperty, b);

ويعمل بشكل جيد ، ومع ذلك لا أستطيع أن أرى كيفية القيام بذلك في XAML لأنني لا أستطيع العثور على أي وسيلة للتعيين طريق إلى خاصية كائن الخلية.

محاولات XAML واحدة هي:

<Setter Property="FontStyle">
    <Setter.Value>
        <MultiBinding Converter="{StaticResource IsLockedToFontStyleConverter}" Mode="OneWay" UpdateSourceTrigger="PropertyChanged">
              <Binding />
              <Binding RelativeSource="{x:Static RelativeSource.Self}"/>
        </MultiBinding>
    </Setter.Value>
</Setter>

ولكن لا يوجد ملزم بـ مغلق منشأه

public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
    var row = (RowViewModel) values[0];
    var cell = (DataGridCell) values[1];
    if (cell != null && row != null)
    {
        var column = DataGridMethods.GetColumn(cell);
        return row[column].IsLocked ? "Italic" : "Normal";
    }

    return DependencyProperty.UnsetValue;
}

يرجى ملاحظة أن نسخة سابقة تم إرجاعها الصف [العقيد]. وتعيين fontstyle باستخدام datatrigger ولكن الكائن الذي تم إرجاعه ليس قاعدة بيانات.

لاحظ ، بالطبع ، أن التطبيق لا يعرف ما هي الأعمدة في وقت التصميم.

أخيرًا ، لا تعتبر Datatable غير فعالة جدًا لمتطلباتي ، لكنني سأكون مهتمًا بمعرفة كيفية القيام بذلك باستخدام DataTables على أي حال ، إذا كان هناك مثل هذا الحل ، فقد يكون هذا مفيدًا في مكان آخر (على الرغم من أنني أفضل استخدام المجموعات).

من المؤكد أن هذه مشكلة شائعة وأنا أحاول WPF Noobie الذهاب إلى كل MVVM في مشروعي ، لكن هذه المشكلة تعيقني فيما يتعلق باستخدام بيانات WPF.

هل كانت مفيدة؟

المحلول

حسنًا ، هذا هو أبسط الحلول التي وجدتها. (في الواقع كان لدي ذلك قبل أن أنشر هذا والسؤال الآخر ، لكنني شعرت بالحرج من مثل هذا الحل. لم يسمع هذا شيئًا آخر هنا ، وهل في حالة مواجهة أي شخص آخر نفس المشكلة ، اعتقدت أنني سأشاركه.)

ضع إشارة إلى كائن الخلية في خاصية علامة DataGridCell. أفعل ذلك بمزيج من XAML ورمز ملزم داخل المحول على النحو التالي:

   <Setter Property="Tag">
       <Setter.Value>
           <MultiBinding Converter="{StaticResource CellViewModelToTagConverter}" Mode="OneWay" UpdateSourceTrigger="PropertyChanged">
              <Binding />
              <Binding RelativeSource="{x:Static RelativeSource.Self}"/>
          </MultiBinding>
       </Setter.Value>
   </Setter>

و

 public class CellViewModelToTagConverter : IMultiValueConverter
 {
     public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
     {
        var row = values[0] as RowViewModel;
        var cell = values[1] as DataGridCell;
        if (row != null && cell != null)
        {
            var column = DataGridMethods.GetColumn(cell);
            // hack within hack!!! (using tag way is itself a hack?)
            var b = new Binding("Self") {Source = row[column]};
            cell.SetBinding(FrameworkElement.TagProperty, b);
            //...
            //return row[column];
            return DependencyProperty.UnsetValue;
        }
        return DependencyProperty.UnsetValue;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

يمكنك معرفة ما أفكر فيه في هذا الحل من خلال تعليقاتي داخل المحول. (اضطررت إلى إضافة خاصية ذاتية إلى كائن الخلية وجعل الذات = هذا في المنشئ).

لا يزال يتيح أن يكون ترميز البيانات الخاص بي MVVM تمامًا - إذا قبلت أن ما قمت به داخل المحول يتوافق مع MVVM. على أي حال فهو يعمل!

لذا ، يمكنني القيام بذلك بهذه الطريقة ، يمكنني رؤية كل شيء وإدارته من XAML مثل التحكم في هذا الارتباط فقط على أعمدة معينة عن طريق وضع XAML داخل خلايا الخلايا ذات الصلة (هذا لا يفعل ذلك عبر dataGrid.CellStyle).

على أي حال ، مثال على الاستخدام

<Style.Triggers>
      <DataTrigger Value="true" Binding="{Binding RelativeSource={RelativeSource Self}, Path=Tag.IsLocked}">
            <Setter Property="FontStyle" Value="Italic"/>
            <Setter Property="IsEnabled" Value="False"/>
       </DataTrigger>
 </Style.Triggers>

على مستوى XAML ، يكون الأمر بسيطًا وأنيقًا (خاصة بالنسبة لمختلف تلميحات الأدوات والنوافذ المنبثقة التي أقوم بها باستخدام خصائص كائن الخلية). ومع ذلك أنا متأكد من أن هناك طريقة أفضل للقيام بذلك ، هل هناك؟

نأمل أن يزول كل هذا عندما أتمكن من استخدام Net 4.0 والكائنات الديناميكية ، لكن لهذا المشروع لا يمكنني ذلك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top