2015-01-25 2 views
-1

데이터베이스에 정수로 저장된 열거 형 필드가 있습니다. 예 : 1은 개를 의미하고 2는 고양이를 의미합니다.WPF에서 필드를 표시하는 방법을 변경하는 방법?

데이터를 표시 할 때 정수 대신 실제 이름을 표시하고 싶습니다. WPF에서이를 수행하는 가장 좋은 방법은 무엇입니까?

데이터 세트의 값을 row["TYPE"] = Name[row["TYPE"]];과 같이 변경하려고 시도했지만 작동하지 않습니다 (일치하지 않는 데이터 유형).

이 ComboBox를 사용하여 데이터를 가져오고 데이터 유형은 int입니다.

<ComboBox Height="23" Name="typeSelectComboBox" Width="190"> 
      <ComboBoxItem Tag="0" Content="Select" /> 
      <ComboBoxItem Tag="1" Content="Foo" /> 
      <ComboBoxItem Tag="2" Content="Bar" /> 
      <ComboBoxItem Tag="3" Content="Cat" /> 
      <ComboBoxItem Tag="4" Content="Dog" /> 
</ComboBox> 

다음은 데이터를 표시하는 방법입니다.

 string sqlStr = "select * from AREA"; 
     OracleDataAdapter dataAdapter = new OracleDataAdapter(sqlStr, db.Connection); 
     DataSet systemDataSet = new DataSet(); 
     dataAdapter.Fill(systemDataSet); 

     if (systemDataSet.Tables[0].Rows.Count > 0) 
     { 
      /* this doesn't work. 
      foreach (DataRow row in systemDataSet.Tables[0].Rows) 
      { 
       // row["TYPE"] = Name[row["TYPE"]]; 
      } */ 
      areaListGrid.ItemsSource = systemDataSet.Tables[0].DefaultView; 
     } 

는 areaListGrid는 데이터, 특별한 구성을 누르고 기본 ListGrid이다.

<DataGrid AutoGenerateColumns="False" 
     IsReadOnly="True" 
     Grid.Row="1" Height="484" HorizontalAlignment="Left" Margin="3,4,0,0" Name="areaListGrid" VerticalAlignment="Top" Width="668"> 
<DataGrid.Columns> 
    <DataGridTextColumn Binding="{Binding ID}" Header="ID" MaxWidth="30" FontSize="12" /> 
    <DataGridTextColumn Binding="{Binding Path=NAME}" MinWidth="50" Header="Name" FontSize="12" /> 
    <DataGridTextColumn Binding="{Binding Path=TYPE}" MinWidth="10" Header="Type" FontSize="12" /> 
    <DataGridTextColumn Binding="{Binding Path=DESCRIPTION}" MinWidth="300" Header="Location" FontSize="12"> 
     <DataGridTextColumn.ElementStyle> 
      <Style TargetType="TextBlock"> 
       <Setter Property="TextWrapping" Value="Wrap"/> 
       <Setter Property="Height" Value="Auto"/> 
      </Style> 
     </DataGridTextColumn.ElementStyle> 
    </DataGridTextColumn> 
</DataGrid.Columns> 
</DataGrid> 

답변

1

한 유형의 값을 다른 유형의 값으로 매핑하는 순수 XAML 기반 접근 방식에 대해 알고 있지 않습니다. 그러나 :

기본적으로
  • 하는 텍스트 객체에 enum 유형의 WPF 바인딩, TextBlock.Text, Button.Content 등처럼 enum 값 이름을 사용합니다. 이 경우에는 할 일이 없습니다. 값 이름은 바운드 값으로 자동 표시됩니다.
  • 어떤 이유에서든 enum으로 실제로 입력 된 것이 아니라 일반 int으로 바인딩하는 경우 매핑을 수행하고 표시 객체의 바인딩 선언에 사용하는 IValueConverter을 구현할 수 있어야합니다 .

당신이 당신의 바인딩 (즉 enum 종류와 표시합니다 일부 XAML)의 필수적인 부분을 보여줍니다 a good, minimal, complete code example를 제공 할 경우는 더 구체적인 답변을 제공 할 수있다.


편집 :

는 불행하게도, 문제의 코드 예제가 완료되지 않았습니다. 즉, 기본 이슈와 도처에 나타나는 문제를 해결하는 것입니다.

이 "단지 작동"

를 "나는 아직 콤보 상자에 열거를 결합하는 방법을 모른다".

<StackPanel> 
    <TextBlock Text="{Binding ElementName=mainWindow, Path=Value}" /> 
    <ComboBox SelectionChanged="ComboBox_SelectionChanged" SelectedValuePath="Tag"> 
    <ComboBoxItem Tag="{x:Static local:Fruit.Apple}" Content="{x:Static local:Fruit.Apple}" /> 
    <ComboBoxItem Tag="{x:Static local:Fruit.Orange}" Content="{x:Static local:Fruit.Orange}" /> 
    <ComboBoxItem Tag="{x:Static local:Fruit.Banana}" Content="{x:Static local:Fruit.Banana}" /> 
    <ComboBoxItem Tag="{x:Static local:Fruit.Kiwi}" Content="{x:Static local:Fruit.Kiwi}" /> 
    </ComboBox> 
</StackPanel> 
다음 Content 속성 인 예를 들어, 여기서, MainWindow 오브젝트의 현재 열거 된 값을 표시하는 TextBlockTag 속성 열거 값 자체에 할당 된 ComboBox 간단한 XAML 형태 인

참고 enum 특정 값들을 이용하기위한 구문 (물론 enum Fruit { Apple, Orange, Banana, Kiwi } 선언) 가정 : {x:Static local:Fruit.Apple}.localenum의 네임 스페이스를 나타내며 XAML 루트 요소 (XAML 네임 스페이스 등)의 xmlns 특성으로 선언되며 물론 enum 값 자체는 C#에서와 동일하게 지정됩니다 (즉 <enum name>.<enum value>).

TextBlock은 유형이 Fruit 인 속성에 직접 바인딩됩니다.

코드에서 값을 처리 할 때 enum 값을 사용하는 동안 enum 값을 사용자에게 표시 할 때 해당 값으로 변환하여 XAML 컴파일러와 WPF 런타임이 나머지를 처리합니다.

Window 클래스는 다음과 같습니다

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    public Fruit Value 
    { 
     get { return (Fruit)GetValue(ValueProperty); } 
     set { SetValue(ValueProperty, value); } 
    } 
    public static DependencyProperty ValueProperty = 
     DependencyProperty.Register("Value", typeof(Fruit), typeof(MainWindow), new PropertyMetadata(Fruit.Apple)); 

    private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
    { 
     ComboBox comboBox = (ComboBox)sender; 

     Value = (Fruit)comboBox.SelectedValue; 
    } 
} 

즉, 일반 DependencyProperty 기반 속성 및 특정 ComboBoxItem이 선택되면 속성 값을 업데이트하는 이벤트 처리기가 있습니다.

코드 예제에서 DataAdapter이 어떻게 구성되었는지는 명확하지 않습니다. 그러나 DB의 정수를 행의 유형 값 enum으로 자동 변환하도록 설정되었습니다. 이는 테이블 뷰를 WPF UI 객체에 직접 바인딩 할 수 있기 때문에 이상적입니다.

현재 그렇게 설정되어 있지 않다면 그 일에 집중해야합니다. 그러나 실제로 원한다면 WPF UI에 테이블 행을 표시하는 데 사용되는 바인딩에 IValueConverter을 추가 할 수 있어야합니다. 다시 말하지만, areaListGrid과 관련된 세부 사항이 부족한 질문을 통해 정확히 어떻게 할 수 있는지 말할 수는 없습니다. 그러나 다른 IValueConverter과 같이 작동합니다. DB 데이터의 int에서 enum으로 맵핑 할 변환기를 작성하고 해당 값에 대한 DB 컬럼에 대한 바인딩을 사용하십시오.


편집 # 2 :

당신이 실제로 enum 유형을 사용하지 않는 경우, 당신은 명시 적 변환을 처리하는 IValueConverter을 구현할 수 있습니다. 예를 들어 :

class Int32ToValueNameConverter : IValueConverter 
{ 
    private static readonly Dictionary<int, string> _intToName = new Dictionary<int, string>() 
    { 
     { 0, "Apple" }, 
     { 1, "Orange" }, 
     { 2, "Banana" }, 
     { 3, "Kiwi" }, 
    }; 

    private static readonly Dictionary<string, int> _nameToInt = _intToName.ToDictionary(kvp => kvp.Value, kvp => kvp.Key); 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value is int && targetType == typeof(string)) 
     { 
      string result; 

      if (_intToName.TryGetValue((int)value, out result)) 
      { 
       return result; 
      } 
     } 

     return Binding.DoNothing; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     string text = value as string; 

     if (text != null && targetType == typeof(int)) 
     { 
      int result; 

      if (_nameToInt.TryGetValue(text, out result)) 
      { 
       return result; 
      } 
     } 

     return Binding.DoNothing; 
    } 
} 

는이 같은 XAML에서 위를 사용할 수 있습니다 :

<StackPanel> 
    <Button Content="Increment Int" Click="Int32Button_Click" HorizontalAlignment="Left" /> 
    <TextBlock> 
    <TextBlock.Text> 
     <Binding ElementName="mainWindow" Path="Int32Value"> 
     <Binding.Converter> 
      <local:Int32ToValueNameConverter /> 
     </Binding.Converter> 
     </Binding> 
    </TextBlock.Text> 
    </TextBlock> 
    <TextBox> 
    <TextBox.Text> 
     <Binding ElementName="mainWindow" Path="Int32Value" UpdateSourceTrigger="PropertyChanged"> 
     <Binding.Converter> 
      <local:Int32ToValueNameConverter /> 
     </Binding.Converter> 
     </Binding> 
    </TextBox.Text> 
    </TextBox> 
</StackPanel> 

정수 값을 통해 회전합니다 버튼을 클릭하면 TextBlockTextBox 모두에서 결과를 표시. TextBox에 유효한 값 이름을 입력하면 바인딩 된 속성이 업데이트되며 변경 내용을 반영하도록 TextBlock이 업데이트됩니다.

위의 예를 지원하는 코드 숨김 : 나는 당신이 당신의 자신의 DataGrid 시나리오에 바인딩 예를 들어 위의를 적용 할 수 있습니다 내가 생산의 노력에가는 것 같은 느낌하지 않았다 용서 신뢰

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 

    public int Int32Value 
    { 
     get { return (int)GetValue(Int32ValueProperty); } 
     set { SetValue(Int32ValueProperty, value); } 
    } 
    public static DependencyProperty Int32ValueProperty = 
     DependencyProperty.Register("Int32Value", typeof(int), typeof(MainWindow), new PropertyMetadata(0)); 

    private void Int32Button_Click(object sender, RoutedEventArgs e) 
    { 
     int newValue = Int32Value + 1; 

     if (newValue > 3) 
     { 
      newValue = 0; 
     } 

     Int32Value = newValue; 
    } 
} 

을 귀하의 질문에 포함되어 있어야하는 자급 자족적인 DataGrid 예가 제공되었지만 답변을 기반으로 할 수있었습니다.

+0

감사합니다. 코드를 업데이트했습니다.int 형을 데이터 형으로 사용했는데, 이것이 최선의 방법은 아닐지도 모른다. 그러나 나는 Enum을 ComboBox에 바인딩하는 방법을 아직 모르고있다. – leetom

+0

@leetom : 위의 편집을 참조하십시오. –

+0

양해 해 주셔서 감사합니다. 나는 enum을 언급함으로써 실수를 범할 수도있다. 사실 저는 (처음에는 필요 없다고 생각하기 때문에)'enum '타입을 사용하지 않았습니다. 내가 한 모든 것은 이름 (문자열)을 사용자에게 보여주고 데이터를 정수형으로 유지하려고 시도하는 것입니다. 코드 및 데이터베이스. 동적 유형 지정 언어를 사용할 때 일반적으로 그렇게하는 것입니다. 하지만 이제 C#에서'integer' 필드를'string'으로 직접 변경할 수 없습니다. 나는 'IValueConverter'을 구현하려고하는데, 모든 것들이 내가 초보자이기 때문에 새롭다. – leetom

관련 문제