以双向模式更新所选项目的样式

时间:2014-12-04 09:51:38

标签: c# wpf

我有一个包含数据模板列表视图的视图 我需要在所选项目上设置样式 但是我也需要在修改所选项目的代码中修改所选项目的视图

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="50" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}" Width="300" Height="50" TextAlignment="Center"/>
    <ListView Grid.Row="1" ItemsSource="{Binding List, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <ListView.ItemTemplate>
            <DataTemplate >
                <Border BorderThickness="1" BorderBrush="White">
                    <Grid Height="20" Width="30" >
                        <TextBlock  Text="{Binding Name}"/>
                    </Grid>
                </Border>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</Grid>

有列表视图和文本块 我需要在selectedItem更改时更改所选项目的背景

这是viewmodel

 public class MainViewModel : ViewModelBase
{
    private Item selectedItem;
    public ObservableCollection<Item> List { get; set; }
     string text;
     public string Text
     {
         get { return text; }
         set
         {
             text = value;
             OnPropertyChanged("Text");
         }
     }
    public Item SelectedItem
    {
        get { return selectedItem; }
        set{
            if (value.Name != "Test1")
            {
                selectedItem = value;
                Text = value.Name;
            }
            else
            {
                Text = string.Format("Test1 was selected but the selected item is {0}", selectedItem==null?"null":selectedItem.Name);
            }

            OnPropertyChanged("SelectedItem");
        }
    }
    public  MainViewModel()
    {
        List = new ObservableCollection<Item>()
        {
            new Item("Test1","Val1"),new Item("Test2","Val2"),new Item("Test3","Val3"),new Item("Test4","Val"),
        };
        OnPropertyChanged("List");
    }
}
public class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(params string[] propertyNames)
    {
        if (PropertyChanged != null)
        {
            foreach (var propertyName in propertyNames)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                PropertyChanged(this, e);
            }
        }
    }
}
public class Item : ViewModelBase
{
    public string Name { get; set; }
    public string Value { get; set; }
    public Item(string name, string val)
    {
        Name = name;
        Value = val;
        OnPropertyChanged("Name");
    }
}

请注意,当Test1 Item选中时,所选项目没有改变,但在视图中Test1被标记为已选择

1 个答案:

答案 0 :(得分:0)

在视图调用MainViewModel.SelectedItem setter时,视图已更新列表中的所选项。绑定简单地通知VM这个事实。您没有设置MainViewModel.selectedItem这一事实对视图毫无意义。

您会认为提升OnPropertyChanged("SelectedItem");会强制视图重新评估其所选项目,但实际上这不起作用。我假设是在WPF中进行一些优化或防止循环绑定更新。 (请记住,您已经将setter作为绑定更新的一部分进行调用,并且您正尝试再次更新绑定)

如果您希望阻止在视图中选择某些内容,则需要在视图中将其禁用,然后才能进入VM。 Here is one way of doing this