2015-09-07 103 views
0

我在这个应用程序中有一个统一的网格。在调整窗口大小(当宽度为< 300时)时,它会从网格中删除右列,并更改IsEnabled=false项目。恢复到以前的大小(宽度> 300)后,它会添加删除的列及其元素。但似乎不起作用。回复元素后仍然IsEnabled=false为什么?可观察集合深拷贝

namespace WpfApplication1 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public Cars cars; 
     public MainWindow() 
     { 
      cars = new Cars(); 
      InitializeComponent(); 
      DataContext = cars; 
     } 

     public ObservableCollection<CarType> temp; 

     public bool Crutch; 
     private void Window_SizeChanged(object sender, SizeChangedEventArgs e) 
     { 
      if (e.NewSize.Width<300) 
      { 
       if (cars.Items.Count == 4) 
       { 
        cars.Columns = 1; 
        cars.Rows = 2; 
        temp = new ObservableCollection<CarType>(from x in cars.Items select (CarType)x.Clone());   
        cars.Items.ToList().GetRange(2, 2).ForEach(x => x.IsEnabled = false); 
        Crutch = true; 
       } 
      } 
      if (e.NewSize.Width>300) 
      { 
       if (Crutch) 
       { 
        cars.Items = temp; 
        cars.Columns = 2; 
        cars.Rows = 2; 
        Crutch = false; 
       } 
      } 
     } 
    } 
    public class CarType:ICloneable,INotifyPropertyChanged 
    { 
     public int number { get; set; } 
     public DateTime date { get; set; } 
     public string comments { get; set; } 

     public bool isEnabled; 
     public bool IsEnabled 
     { 
      get 
      { 
       return this.isEnabled; 
      } 

      set 
      { 
       this.isEnabled = value; 
       RaisePropertyChaged("IsEnabled"); 
      } 
     } 
     public CarType() 
     { 
      IsEnabled = true; 
     } 
     public event PropertyChangedEventHandler PropertyChanged; 

     private void RaisePropertyChaged(string info) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 

     public object Clone() 
     { 
      return new CarType { number=this.number,IsEnabled=this.IsEnabled,date=this.date,comments=this.comments}; 
     } 
    } 
    public class Cars:INotifyPropertyChanged 
    { 
     private int rows; 

     private int columns; 
     public int Rows 
     { 
      get 
      { 
       return this.rows; 
      } 

      set 
      { 
       this.rows = value; 
       RaisePropertyChaged("Rows"); 
      } 
     } 
     public int Columns 
     { 
      get 
      { 
       return this.columns; 
      } 

      set 
      { 
       this.columns = value; 
       RaisePropertyChaged("Columns"); 
      } 
     } 

     private ObservableCollection<CarType> items; 
     public ObservableCollection<CarType> Items 
     { 
      get 
      { 
       return this.items; 
      } 

      set 
      { 
       this.items = value; 
       RaisePropertyChaged("Items"); 
      } 
     } 
     public Cars() 
     { 
      Rows = 2; 
      Columns = 2; 
      Items = new ObservableCollection<CarType>(); 
      Items.Add(new CarType { comments = "First", date =DateTime.Now, number = 1 }); 
      Items.Add(new CarType { comments = "First", date = DateTime.Now, number = 2 }); 
      Items.Add(new CarType { comments = "First", date = DateTime.Now, number = 3 }); 
      Items.Add(new CarType { comments = "First", date = DateTime.Now, number = 4 }); 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

     private void RaisePropertyChaged(string info) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(info)); 
     } 
    } 
} 

XAML

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="250" Width="500" SizeChanged="Window_SizeChanged"> 
<Canvas> 
    <ItemsControl ItemsSource="{Binding Items}"> 
     <ItemsControl.ItemsPanel> 
      <ItemsPanelTemplate> 
       <UniformGrid Columns="{Binding Columns}" Rows="{Binding Rows}"></UniformGrid> 
      </ItemsPanelTemplate> 
     </ItemsControl.ItemsPanel> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate> 
       <Border BorderBrush="Bisque" BorderThickness="1"> 
       <Grid Width="200" Height="100" IsEnabled="{Binding IsEnabled}"> 
        <Grid.RowDefinitions> 
         <RowDefinition></RowDefinition> 
         <RowDefinition></RowDefinition> 
         <RowDefinition></RowDefinition> 
        </Grid.RowDefinitions> 
        <Label Grid.Row="0" Content="{Binding number}"></Label> 
        <Label Grid.Row="1" Content="{Binding date}"></Label> 
        <Label Grid.Row="2" Content="{Binding comments}"></Label> 
       </Grid> 
       </Border> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 
</Canvas> 

回答

2

窗口的SizeChanged事件被触发反复当你调整窗口的大小,你可能希望它是只有当它的大小是“已确定”一旦发射(当你停止调整窗口大小时),但这是不正确的。

所以这条线被反复调用,当你从拉窄于300窗口宽度超过300

temp = new ObservableCollection<CarType>(from x in cars.Items select (CarType)x.Clone()); 

所以,你正在CarTypes的深备份的IsEnabled =假。

并回答您的评论你的问题是“如何做出正确复制”:

,您可根据原件,然后当你需要重新使用原始副本的副本启用网格。

ObservableCollection<CarType> originalCopy; 
public MainWindow() 
{ 
    cars = new Cars(); 
    originalCopy = new ObservableCollection<CarType>(from x in cars.Items select (CarType)x.Clone()); 
    .... 
} 

而当你需要的原件这个副本:

if (e.NewSize.Width>300) 
{ 
    if (Crutch) 
    { 
     cars.Items = new ObservableCollection<CarType>(from x in originalCopy select (CarType)x.Clone()); 

这样,您的原件是否完好(他们IsEnbled属性始终为true)。

但是...

我建议您不要使用 “复制”,只用一个ItemSource(cars.Items),并相应地更改IsEnabled属性。复制项目,然后重新绑定没有多大意义。

我的意思是(其他代码是为更好的解释删除)

if (e.NewSize.Width < 300) 
{ 
    cars.Items.ToList().GetRange(2, 2).ForEach(x => x.IsEnabled = false); 
} 
else //e.NewSize.Width >= 300 
{ 
    cars.Items.ToList().GetRange(2, 2).ForEach(x => x.IsEnabled = true); 
} 
+0

你能不能指点如何作出正确的副本? – A191919