2016-11-03 7 views
0

私は、ItemsSourceが私のViewModelのコレクションプロパティに設定されているListViewを持っています。 ViewModelには、コードが実行されるときに変更される 'CurrentIndex'というプロパティもあります。これが変わると、リストビューのインデックスが 'CurrentIndex'と一致するListViewItemだけが変更され、その背景が色を変更するようになります。 'CurrentIndex'が変更されると、以前に参照されたListViewItemが 'リセット'されます。つまり、背景が以前の色に変更されます。誰も私はこれを達成するかもしれません知っていますか?ViewModelの変更値に一致するインデックスを持つ特定のListViewItemの背景を変更するにはどうすればよいですか?

ListViewのSelectedIndexプロパティを悪用しようと考えましたが、ユーザーがListViewをクリックして選択項目を変更して間違った項目の背景を変更できるため、これは機能しません。

ListViewItemは、XAMLのItemTemplateを介してテンプレート化されています。

希望はこれが理にかなっています。

事前のお手伝いがあります。

+0

ItemCountが過剰でない場合は、コンバータで 'AlternationIndex'を使用できます。 AlternationIndexの使用例は、[here](http:// stackoverflow。com/a/6512032/302677) – Rachel

+0

@Rachel、ご返信ありがとうございます。私はそれに落とし穴がなかった「クリーナー」なアプローチを望んでいました。 – Cleve

+1

'CurrentIndex'を'ItemCollection [CurrentIndex]'を返す 'CurrentItem'に変更し、' IMultiValueConverter'を使って 'CurrentItem == Value'を参照するようにします。両方の値をConverterに渡すのに十分なはずです。あなたがそれを必要とすれば、私はおそらく何らかの例を見つけることができます。 – Rachel

答えて

1

第二の溶液:

<ListView ItemsSource="{Binding MyItemsList}"> 
     <ListView.ItemTemplate> 
      <ItemContainerTemplate> 
       <Grid> 
        <Grid.Style> 
         <Style TargetType="Grid"> 
          <Setter Property="Background" Value="Transparent"/> 
          <Style.Triggers> 
           <DataTrigger Binding="{Binding ShouldChangeBackground}" Value="true"> 
            <Setter Property="Background" Value="Red"/> 
           </DataTrigger> 
          </Style.Triggers> 
         </Style> 
        </Grid.Style> 

       </Grid> 
      </ItemContainerTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 

ShouldChangeBackgroundブールです:

あなたはこれを行うことがListViewコントロールのItemsSourceにバインドされ、各項目が実装INotifyPropertyChangedのいる項目の配列を、持っている場合アイテム内。また、このブール値をtrueに設定し、バックグラウンドカラーを変更してから通常に戻す必要がある場合はFalseに設定します。

class TrueToBackgroundConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is Boolean && (Boolean)value) 
      return Brushes.Red; 

     return Brushes.Transparent; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

し、あなたのコード内:

<ListView ItemsSource="{Binding Element, FallbackValue=123123213213123213213}"> 
     <ListView.ItemTemplate> 
      <ItemContainerTemplate> 
       <Grid Background="{Binding ShouldChangeBackground, Converter={StaticResource TrueToBackgroundConverter}}"> 
       </Grid> 
      </ItemContainerTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 
+0

こんにちはLupu Silviu、私の元の記事では、私はListViewのSelectedIndexプロパティを使用しようとしたと述べた。その問題、おそらくSelectedItem(またはSelectedValue)の問題は、ユーザーがListivewをクリックして、これらのプロパティーを意図したCurrentIndex値から変更できることです。私があなたの答えを誤解していると感じたらコードを投稿してください。ありがとう – Cleve

+0

実際に、ViewModelで処理されている特定の要素の背景の色を変更したいのですが、そうですか?ビューのSelected要素には必ずしも関連付けられていません。 –

+0

はい、そうです。 – Cleve

2

ここでそれを行うための別の方法があります

別の解決策は、コンバータを使用することができます。あなたはa behavior that applies to WPF container controls like Grid, StackPanel, etc., and gives each of the children an attached ChildIndex propertyで始まります。次にItemContainerStyleListBoxDataTriggerを追加し、MultiBindingと多値コンバータを使用して、ListBoxItemChildIndexとビューモデルのHighlightIndexプロパティをそれぞれ比較します。

それは(本当に、あなたはListBoxの上位クラスItemsControlにそれを適用したいと思います)ListBox自体に適用される行動のために、より便利になりますが、それはあるとして、あなたはその事にそれを使用することができますリストボックスにはありません。

XAML:

<ListBox 
    ItemsSource="{Binding Items}" 
    > 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <StackPanel 
       hbo:PanelBehaviors.IsChildPositionIndicated="True" 
       Orientation="Vertical" 
       /> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
    <ListBox.ItemContainerStyle> 
     <Style 
      TargetType="ListBoxItem" 
      BasedOn="{StaticResource {x:Type ListBoxItem}}" 
      > 
      <Style.Triggers> 
       <DataTrigger Value="True"> 
        <DataTrigger.Binding> 
         <MultiBinding 
          Converter="{StaticResource EqualsConverter}"> 
          <Binding 
           Path="DataContext.HighlightIndex" 
           RelativeSource="{RelativeSource AncestorType=ListBox}" 
           /> 
          <Binding 
           Path="(hbo:PanelBehaviors.ChildIndex)" 
           RelativeSource="{RelativeSource Self}" 
           /> 
         </MultiBinding> 
        </DataTrigger.Binding> 
        <Setter Property="Background" Value="Red" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 

行動:

using System.Windows; 
using System.Windows.Controls; 

namespace HollowEarth.Behaviors 
{ 
    public static class PanelBehaviors 
    { 
     public static void UpdateChildIndexProperties(Panel panel) 
     { 
      for (int i = 0; i < panel.Children.Count; ++i) 
      { 
       var child = panel.Children[i]; 
       SetChildIndex(child, i); 
      } 
     } 

     #region PanelBehaviors.IsChildPositionIndicated Attached Property 
     public static bool GetIsChildPositionIndicated(Panel panel) 
     { 
      return (bool)panel.GetValue(IsChildPositionIndicatedProperty); 
     } 
     public static void SetIsChildPositionIndicated(Panel panel, bool value) 
     { 
      panel.SetValue(IsChildPositionIndicatedProperty, value); 
     } 

     /// <summary> 
     /// Behavior which causes the Panel to identify its first and last children with attached properties. 
     /// </summary> 
     public static readonly DependencyProperty IsChildPositionIndicatedProperty = 
      DependencyProperty.RegisterAttached("IsChildPositionIndicated", typeof(bool), typeof(PanelBehaviors), 
       new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsArrange, IsChildPositionIndicated_PropertyChanged)); 
     private static void IsChildPositionIndicated_PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
     { 
      Panel panel = (Panel)d; 
      ((Panel)d).LayoutUpdated += (s, e2) => UpdateChildIndexProperties(panel); 
     } 
     #endregion PanelBehaviors.IsChildPositionIndicated Attached Property 

     #region PanelBehaviors.ChildIndex Attached Property 
     public static int GetChildIndex(UIElement obj) 
     { 
      return (int)obj.GetValue(ChildIndexProperty); 
     } 

     public static void SetChildIndex(UIElement obj, int value) 
     { 
      obj.SetValue(ChildIndexProperty, value); 
     } 

     public static readonly DependencyProperty ChildIndexProperty = 
      DependencyProperty.RegisterAttached("ChildIndex", typeof(int), typeof(PanelBehaviors), 
       new FrameworkPropertyMetadata(-1, 
        FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsParentArrange)); 
     #endregion PanelBehaviors.ChildIndex Attached Property 
    } 
} 

コンバータ:ObservableCollection<String> Itemsint HighlightIndex { get; set; }INotifyPropertyChangedと:

public class EqualsConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     return Object.Equals(values[0], values[1]); 
    } 

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

のviewmodelはちょうど急ごしらえです。

+0

提案とコードに感謝します。さまざまなオプションを使って作業しています。 – Cleve

+0

@Cleve Groovy Rachel's AlternationCountのアイデアは面白いと思う。それが働くならばるかに軽量です。 –

関連する問題