6

テキスト ボックスがあり、それをオートコンプリート テキスト ボックスにしたいと考えています。テキストボックスを入力したときに表示するデータは、データグリッドからのものです。私のデータグリッドには 4 つの列があり、データグリッドから任意の列を選択できます。

ここに私のテキストボックスがあります

         <TextBox Margin="0,93,39,18" Grid.Column="1" HorizontalAlignment="Right" Width="325">
            <TextBox.Style>
                <Style TargetType="TextBox">
                    <Style.Triggers>
                        <Trigger Property="Text" Value="">
                            <Setter Property="Background" Value="{StaticResource SearchHint}"/>
                        </Trigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>

データグリッド

    <DataGrid Name="Datagrid"  ItemsSource="{Binding Messages}" Margin="4,0,380,413" Grid.Row="1" AutoGenerateColumns="False"  
    IsReadOnly="True"  RowBackground="WhiteSmoke" >

私はグーグルで検索しましたが、取得したサンプルのほとんどは WPF/MVVM パターンに従っていません。私がやろうとしていることは、テキストブロックデータをグリッドアイテムにバインドすることです.誰かが私にどこから始めるべきかを教えてくれますか.

4

1 に答える 1

8

この質問にアプローチするにはさまざまな方法がありますが、間違いなく最も顕著なのは編集可能なコンボボックス戦略です (Microsoft の WPF 試験でこれについて多くの質問があり、MVVM パターンを完全に無視していますが、それは別の問題です)。例を挙げて説明します。最初のステップは、コンボボックスとデータグリッドをコーディングすることです...

  <StackPanel>
            <ComboBox
             IsEditable="True"
             IsTextSearchEnabled="True"
             IsSynchronizedWithCurrentItem="True"
             SelectedItem="{Binding MySelectedItem, Mode=TwoWay}"
             ItemsSource="{Binding MyItems}"
            >
                <ComboBox.InputBindings>
                    <KeyBinding  Key="Enter" Command="{Binding NotImplementedCommand}"/>
                </ComboBox.InputBindings>
            </ComboBox>
                <DataGrid
                ItemsSource="{Binding DriveList}"
                AutoGenerateColumns="True"
                />
        </StackPanel>

そして、ビューモデルを作成します...

public class ViewModel :INotifyPropertyChanged
{
    public ObservableCollection<string> MyItems { get; set; }
    public ObservableCollection<DriveInfo> DriveList { get; set; }
    public event PropertyChangedEventHandler PropertyChanged;
    public ViewModel()
    {
        MyItems = new ObservableCollection<string>();
        DriveList = new ObservableCollection<DriveInfo>();
        foreach (DriveInfo di in DriveInfo.GetDrives())
        {
            DriveList.Add(di);
        }
        DriveListCollectionChanged(null, null);
        DriveList.CollectionChanged += DriveListCollectionChanged;

    }
    void DriveListCollectionChanged(object sender, 
                        System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        MyItems.Clear();
        List<string> temp = new List<string>();
        foreach (DriveInfo di in DriveList)
        {// add 4 columns from the DataGrid to the auto complete source
            temp.Add(di.Name);
            temp.Add(di.DriveType.ToString());
            if (di.IsReady)
            {
                temp.Add(di.DriveFormat);
                temp.Add(di.TotalSize.ToString());
                temp.Add(di.AvailableFreeSpace.ToString());
            }
        }
        foreach (string s in temp.Distinct())
        {
            MyItems.Add(s);
        }
    }
    private string _mySelectedItem;
    public string MySelectedItem
    {
        get { return _mySelectedItem; }
        set
        {
            if (value != _mySelectedItem)
            {
                _mySelectedItem = value;
                OnPropertyChanged("MySelectedItem");
            }
        }
    }
    private void OnPropertyChanged(string s)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(s));
        }
    }
}

この例では、DataGrid のソースが変更されたイベントを中断し、コンボ ボックスに複数の列を設定します。単一の列だけを実行している場合、ここでの解決策は異なります。コンボボックスをデータに自動的にバインドできるいくつかのバインドの難解な方法もありますが、質問した内容と、異種の文字列の複数の列をコンボボックスに追加する意図を考えると、その教訓的な価値は疑問です。

上記のイベント ハンドラーはデモンストレーションのみを目的としているため、アプリをデプロイする前にイベント ハンドラーを最適化する必要があります。

これを接続するには、これ (またはその代替) を Xaml に配置します...

   <Window.Resources>
        <wpfApplication3:ViewModel  x:Key="ViewModel"/>
    </Window.Resources>
    <Grid DataContext="{StaticResource ViewModel}">
        <!-- your xaml -->
    </Grid>  

上記の ViewModel クラスは MVVM 準拠のソリューションであり、このクラスのインスタンスを表示ビューの DataContext にバインドします。

于 2013-06-20T16:37:40.130 に答える