2017-04-13 39 views
0

後,我用觀察的集合來UDPATE從INotifyPropertyChange更改顏色並不影響性能變化讀取XML

繼承一個類但是當我改變文本框的顏色不會更改的屬性和PropertyChanged保持無效和沒有按」觸發。在第一次改變它不是null。但在第一次更改後它始終爲空。

附上我的代碼:

namespace COMSimulator 
{ 

    [XmlRoot("SerialPortsColors")] 
    public class SerialPortsColors: ObservableCollection< COM> 
    { 

    } 

    public class COM : INotifyPropertyChanged 
    { 

     private string name; 
     private string color; 

     [XmlAttribute("Name")] 
     public string Name 
     { 
      get 
      { 
       return name; 
      } 
      set 
      { 
       name = value; 
       OnProperyChanged(name); 
      } 
     } 

     [XmlAttribute("Color")] 

     public string Color 
     { 
      get 
      { 
       return color; 
      } 
      set 
      { 
       OnProperyChanged(value); 
       color = value; 

      } 
     } 

     public COM() 
     { 
      name = ""; 
      color = ""; 
     } 

     public event PropertyChangedEventHandler PropertyChanged; 

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

窗口隱藏代碼:

public partial class colorPickerWindow : Window 
{ 

    private SerialPortsColorReadWriteXML _SerialPortsColorReadWriteXML;   
    public colorPickerWindow() 
    { 
     InitializeComponent();    
     updateSerialPorts(); 
     _SerialPortsColorReadWriteXML = new SerialPortsColorReadWriteXML();    
     string err = _SerialPortsColorReadWriteXML.ReadXML(); 
     if (err != "") 
     { 
      MessageBox.Show(err); 
      return; 
     } 
     LBSerialAndColors.ItemsSource = _SerialPortsColorReadWriteXML.LSerialPortsColors; 

    } 

    private void updateSerialPorts() 
    { 

     string [] PortName = System.IO.Ports.SerialPort.GetPortNames(); 
     for (int i = 0; i <PortName.Length; i++) 
     { 
      CB_SelecComPort.Items.Add(PortName[i]); 
     } 

    } 

    private void btnAdd_Click(object sender, RoutedEventArgs e) 
    { 

     string err=""; //case there is an error 
     string COM_TEXT = CB_SelecComPort.Text; 
     MySerialPort.FuncConverstion.checkComName(ref COM_TEXT,ref err); 

     if (_colorPicker.SelectedColor == null) 
     { 
      MessageBox.Show("Please Select a color"); 
      return; 
     } 
     if (err!="") 
     { 
      MessageBox.Show(err); 
      return; 
     } 

     for (int i = 0; i < _SerialPortsColorReadWriteXML.LSerialPortsColors.Count; i++) 
     { 
      if (_SerialPortsColorReadWriteXML.LSerialPortsColors[i].Name == CB_SelecComPort.Text) 
      { 
       _SerialPortsColorReadWriteXML.LSerialPortsColors[i].Color = _colorPicker.SelectedColor.Value.R.ToString("X2") + _colorPicker.SelectedColor.Value.G.ToString("X2") + _colorPicker.SelectedColor.Value.B.ToString("X2") + _colorPicker.SelectedColor.Value.A.ToString("X2"); //R G B A      
       _SerialPortsColorReadWriteXML.WriteXML(); 
       _SerialPortsColorReadWriteXML.ReadXML(); 
       MessageBox.Show("Serial Port and Color has been updated"); 
       return; 
      } 

     } 

     COM NewCom = new COM(); 
     NewCom.Color = _colorPicker.SelectedColor.Value.R.ToString("X2") + _colorPicker.SelectedColor.Value.G.ToString("X2") + _colorPicker.SelectedColor.Value.B.ToString("X2") + _colorPicker.SelectedColor.Value.A.ToString("X2"); //R G B A      
     NewCom.Name = CB_SelecComPort.Text; 
     _SerialPortsColorReadWriteXML.LSerialPortsColors.Add(NewCom); 
     _SerialPortsColorReadWriteXML.WriteXML(); 
     _SerialPortsColorReadWriteXML.ReadXML(); 
     MessageBox.Show("Serial Port and Color has been updated"); 
    } 
} 



public class COMColorConverter: IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     string Color_bytes = value.ToString(); 
     string R = Color_bytes[0].ToString() + Color_bytes[1].ToString(); 
     string G = Color_bytes[2].ToString() + Color_bytes[3].ToString(); 
     string B = Color_bytes[4].ToString() + Color_bytes[5].ToString(); 
     string A = Color_bytes[6].ToString() + Color_bytes[7].ToString(); 

     Color _Color = new Color(); 
     _Color.R = byte.Parse(R,System.Globalization.NumberStyles.AllowHexSpecifier); 
     _Color.G = byte.Parse(G, System.Globalization.NumberStyles.AllowHexSpecifier); 
     _Color.B = byte.Parse(B, System.Globalization.NumberStyles.AllowHexSpecifier); 
     _Color.A = byte.Parse(A, System.Globalization.NumberStyles.AllowHexSpecifier); 

     SolidColorBrush SCB = new SolidColorBrush(_Color); 
     return SCB; 



    } 

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


public class SerialPortsColorReadWriteXML: 
{ 

    private SerialPortsColors _LSerialPortsColors; 


    public SerialPortsColorReadWriteXML() 
    { 

     _LSerialPortsColors = new SerialPortsColors(); 
    } 

    public SerialPortsColors LSerialPortsColors 
    { 
     get 
     { 
      return _LSerialPortsColors; 
     } 

     set 
     { 
      _LSerialPortsColors = value; 

     } 

    } 
    private string path = "SerialPortsColors.xml";   



    /// <summary> 
    /// read the serial ports color XML 
    /// </summary> 
    /// <returns>In Case of an error return the error</returns> 
    public string ReadXML() 
    {    
     XmlSerializer serializer = new XmlSerializer(typeof(SerialPortsColors)); 
     try 
     { 
      using (XmlReader reader = XmlReader.Create(path)) 
      { 
       LSerialPortsColors = (SerialPortsColors)serializer.Deserialize(reader);      
      } 
      return ""; 
     } 

     catch (Exception) 
     { 
      return "There is an issue with the path of the Serial Ports Color XML"; 

     } 


    } 


    public string WriteXML() 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(SerialPortsColors)); 
     try 
     { 
      XmlWriterSettings xws = new XmlWriterSettings(); 
      xws.Indent = true; 
      using (XmlWriter writer = XmlWriter.Create(path, xws)) 
      { 



       serializer.Serialize(writer, LSerialPortsColors); 
      } 

      return ""; 
     } 

     catch 
     { 
      return "There is an issue Creating a new XML File"; 

     }    

    } 





} 

XAML:

<Window x:Class="COMSimulator.colorPickerWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"   
    xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" 
    xmlns:Converters="clr-namespace:COMSimulator" 

    Title="colorPickerWindow" Height="400" Width="300" WindowState="Normal" WindowStartupLocation="CenterScreen" ResizeMode="NoResize"> 

<Window.Resources> 
    <Converters:COMColorConverter x:Key="COMColorConverter" /> 
</Window.Resources> 

<Grid> 

    <Grid.Resources> 
     <DataTemplate x:Key="COMColorTemplate"> 
      <Border BorderBrush="Black" BorderThickness="1"> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="1*"></ColumnDefinition> 
         <ColumnDefinition Width="1*"></ColumnDefinition> 
        </Grid.ColumnDefinitions> 
        <TextBox Grid.Column="0" Text="{Binding Path=Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged }" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" /> 
        <TextBlock Grid.Column="1" HorizontalAlignment="Left" Width="150" Background="{Binding UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, Path=Color, Converter={StaticResource COMColorConverter}}" ></TextBlock>            
      </Grid> 
      </Border> 
     </DataTemplate> 
    </Grid.Resources> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="120"/> 
     <RowDefinition Height="3"/> 
     <RowDefinition Height="1*"/> 
    </Grid.RowDefinitions> 
    <Border Grid.Row="0" Grid.Column="0" BorderThickness="1" BorderBrush="Black"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="1*"></RowDefinition> 
      <RowDefinition Height="10"></RowDefinition> 
      <RowDefinition Height="1*"></RowDefinition> 
      <RowDefinition Height="10"></RowDefinition> 
      <RowDefinition Height="1*"></RowDefinition> 
     </Grid.RowDefinitions> 

     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="1*"></ColumnDefinition> 
      <ColumnDefinition Width="1*"></ColumnDefinition> 
      <ColumnDefinition Width="5"></ColumnDefinition> 

      </Grid.ColumnDefinitions> 

     <Label Content="Select COM Port:" VerticalAlignment="Center" HorizontalAlignment="Center"></Label> 
     <ComboBox x:Name="CB_SelecComPort" Grid.Column="1" Grid.Row="0" VerticalAlignment="Center"></ComboBox> 
     <Label Content="Select Color:" VerticalAlignment="Center" Grid.Row="2" Grid.Column="0" HorizontalAlignment="Center"></Label> 
     <xctk:ColorPicker x:Name="_colorPicker" Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" /> 
     <Button x:Name="btnAdd" Content="Add Or Edit" Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center" Width="150" Click="btnAdd_Click"></Button> 
    </Grid> 
    </Border> 

    <Border Grid.Row="2" Grid.Column="0" BorderThickness="1" BorderBrush="Black" > 
     <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> 
      <ListBox x:Name="LBSerialAndColors" ItemTemplate="{DynamicResource COMColorTemplate}" > 

      </ListBox> 
     </ScrollViewer> 
    </Border> 
</Grid> 
</Window> 
+0

*「proerty變化留空,不會觸發「* - 你是說你在'OnProperyChanged()'中放置了一個斷點,並且你發現'PropertyChanged'事件總是空的?你是說它永遠不會進入這個「if」陳述的主體嗎? –

+0

第一次更改它不爲null。但在第一次改變之後,一切都是空的 –

+0

我通過更新Item來解決了這個問題。添加命令: LBSerialAndColors.ItemsSource = _SerialPortsColorReadWriteXML.LSerialPortsColors;更新數據後 有沒有辦法避免它? –

回答

0

問題是班上的XML出現在這裏SerialPortsColorReadWriteXML沒有繼承,我readed:INotifyPropertyChanged的

public class SerialPortsColorReadWriteXML:INotifyPropertyChanged 
{ 

    private SerialPortsColors _LSerialPortsColors; 


    public SerialPortsColorReadWriteXML() 
    { 

     _LSerialPortsColors = new SerialPortsColors(); 
    } 

    public SerialPortsColors LSerialPortsColors 
    { 
     get 
     { 
      return _LSerialPortsColors; 
     } 

     set 
     { 
      _LSerialPortsColors = value; 
      OnProperyChanged("LSerialPortsColors"); 
     } 

    } 
    private string path = "SerialPortsColors.xml";   



    /// <summary> 
    /// read the serial ports color XML 
    /// </summary> 
    /// <returns>In Case of an error return the error</returns> 
    public string ReadXML() 
    {    
     XmlSerializer serializer = new XmlSerializer(typeof(SerialPortsColors)); 
     try 
     { 
      using (XmlReader reader = XmlReader.Create(path)) 
      { 
       LSerialPortsColors = (SerialPortsColors)serializer.Deserialize(reader);      
      } 
      return ""; 
     } 

     catch (Exception) 
     { 
      return "There is an issue with the path of the Serial Ports Color XML"; 

     } 


    } 


    public string WriteXML() 
    { 
     XmlSerializer serializer = new XmlSerializer(typeof(SerialPortsColors)); 
     try 
     { 
      XmlWriterSettings xws = new XmlWriterSettings(); 
      xws.Indent = true; 
      using (XmlWriter writer = XmlWriter.Create(path, xws)) 
      { 



       serializer.Serialize(writer, LSerialPortsColors); 
      } 

      return ""; 
     } 

     catch 
     { 
      return "There is an issue Creating a new XML File"; 

     }    

    } 




    public event PropertyChangedEventHandler PropertyChanged; 

    private void OnProperyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
} 
+0

還記得我問你是否替換了LSerialPortsColors?下一次,回答人們問你的問題,我們正在努力提供幫助。 –

1

你應該通過物業的名字到OnPropertyChanged方法,即OnProperyChanged("Name")而不是OnProperyChanged(name)

public string Name 
{ 
    get 
    { 
     return name; 
    } 
    set 
    { 
     name = value; 
     OnProperyChanged("Name"); 
    } 
} 

[XmlAttribute("Color")] 
public string Color 
{ 
    get 
    { 
     return color; 
    } 
    set 
    { 
     color = value; 
     OnProperyChanged("Color"); 
    } 
} 

另外,還要確保你之前設置的支持字段你提高PropertyChanged事件。

編輯:正如評論說@約翰,你可以使用nameof運營商在C#6或更高版本:

OnProperyChanged(nameof(Color)); 

編輯2: 這是一個有點不清楚你希望發生什麼但是如果要設置顯示在ListBox中的實際項目的NameColor屬性,則應重複以下操作:

foreach(var item in LBSerialAndColors.Items.OfType<COM>()) 
{ 
    if (item.Name == CB_SelecComPort.Text) 
    { 
     item.Color = _colorPicker.SelectedColor.Value.R.ToString("X2") + _colorPicker.SelectedColor.Value.G.ToString("X2") + _colorPicker.SelectedColor.Value.B.ToString("X2") + _colorPicker.SelectedColor.Value.A.ToString("X2"); //R G B A      
     MessageBox.Show("Serial Port and Color has been updated"); 
     return; 
    } 
} 

如果每次調用屬性時_SerialPortsColorReadWriteXML.LSerialPortsColors都會返回新對象,那麼遍歷這些對象就沒有意義了。

+0

請注意,從C#6開始,可以使用'nameof(..)',它將在編譯時轉換爲字符串。例如:'OnPropertyChanged(nameof(Color));' – john

+0

是的,我知道,但由於不清楚哪個版本的OP正在使用我使用的語法也適用於以前的版本。 – mm8

+0

您好我有同樣的問題仍然改變:( –

2

在更改顏色之前,您正在通知UI您的顏色已更改。試試這個:

public string Color 
{ 
    get 
    { 
     return color; 
    } 
    set 
    { 

     color = value; 
     OnProperyChanged("Color"); 

    } 
} 
+0

改變它仍然沒有幫助:( –

+0

是LSerialPortsColor一個ObservableCollection ? –

+0

您可以發佈您COMColorConverter的代碼也? –