2017-01-10 6 views
0

小さなwpfプロジェクトで、C#とmvvmをよく理解しています。 現在、私は2ページ間でデータを渡す方法はわかりませんが、現在問題があります。 私は何をしたいですか: 私は2ページあり、それらは私のMainWindowの内容です。 PageViewCustomersで私はDatagridViewを持っています(2つありますが、このタスクに必要なのは1つだけです)、行をダブルクリックすると、PageAddStaticIPAddressが開きます。これで、PageAddStaticIPAddressのPageViewCustomersでダブルクリックされた行にアクセスできるようになりました。私は、PageViewCustomersのxamlにCommandParameterとして選択した行を渡すことを考えました。 しかし、私はPageAddStaticIPAddressからアクセスする方法を知りません。 私はいくつかの解決策を見てきましたが、それらはすべてViewでCodeを持つことで解決しました。私は可能な限りビュー内に少ないコードしか持たず、Bindings、コマンド、および私のビューモデルを使って解決します。C#データを2つのページ間で渡すWPF MVVM

ここに私の現在のコードです:

PageViewCustomers.xaml

<Page x:Class="StaticIPConfiger.PageViewCustomers" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:StaticIPConfiger" 
    xmlns:localvm="clr-namespace:StaticIPConfiger.Modelle" 
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="500" 
    Title="Kundenübersicht"> 
<Page.DataContext> 
    <localvm:VModel /> 
</Page.DataContext> 

<Grid DataContext="{Binding}" > 
    <DataGrid IsReadOnly="True" Name="dgCustomers" ItemsSource="{Binding AlleKunden}" AutoGenerateColumns="False" Margin="0,0,0,197"> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="Name" Binding="{Binding Path=c_name}" Width="*"></DataGridTextColumn> 
      <DataGridTextColumn Header="Standort" Binding="{Binding Path=l_name}" Width="*"></DataGridTextColumn> 
     </DataGrid.Columns> 
     <i:Interaction.Triggers> 
      <i:EventTrigger EventName="SelectionChanged"> 
       <i:InvokeCommandAction Command="{Binding UpdateLocations}" 
       CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=SelectedItem}" /> 
      </i:EventTrigger> 
     </i:Interaction.Triggers> 
    </DataGrid> 
    <DataGrid IsReadOnly="True" Name="dg2Customers" ItemsSource="{Binding AlleStandorte}" AutoGenerateColumns="False" Margin="0,168,0,10" > 
     <DataGrid.InputBindings> 
      <MouseBinding Gesture="LeftDoubleClick" Command="{Binding OpenAddNewIPAddress}" 
          CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=SelectedItem}"/> 
     </DataGrid.InputBindings> 
     <DataGrid.Columns> 
      <DataGridTextColumn Header="StandortId" Binding="{Binding Path=l_id}" Width="*"></DataGridTextColumn> 
      <DataGridTextColumn Header="Standort" Binding="{Binding Path=l_name}" Width="*"></DataGridTextColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
</Grid> 

クラスVModel.cs(PageViewCustomersのVModel)

namespace StaticIPConfiger.Modelle { 

public class VModel : INotifyPropertyChanged { 
    DataView _alleKunden; 
    public VModel() { 
     DataTable dt = new DataTable(); 
     using (SqlConnection connection = new SqlConnection("Data Source=.\\WERBASWEB;Initial Catalog=customer;Persist Security Info=True;User ID=sa;Password=Dotnet123!")) { 
      SqlDataAdapter adapter = new SqlDataAdapter(); 
      adapter.SelectCommand = new SqlCommand("Select c_id,c_name, l_id,l_name, a_town, a_pcode, a_street from dbo.[AllCustomers]", connection); 
      adapter.Fill(dt); 
     } 
     AlleKunden = dt.DefaultView; 
     AlleStandorte = null; 

    } 

    public DataView AlleKunden { get; private set; } 

    public DataView AlleStandorte { get { return _alleKunden; } private set { _alleKunden = value; 
      RaisePropertyChanged("AlleStandorte"); 
     } } 

    #region INotifyPropertyChanged Members 
    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion 

    #region Methods 

    private void RaisePropertyChanged(string propertyName) { 
     // take a copy to prevent thread issues 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    #endregion 

    #region Commands 
    void UpdateLocationView(object parameter) { 
     DataRowView selectedRow = (DataRowView)parameter; 
     string customerid = selectedRow.Row[0].ToString(); 
     string locationid = selectedRow.Row[2].ToString(); 
     DataTable dt = SelectStatements.SelectLocationsForCustomer(locationid,customerid); 
     AlleStandorte = dt.DefaultView; 
     Console.WriteLine("Test"); 
    } 

    bool CanUpdateLocationView(object parameter) { 
     return true; 
    } 

    public ICommand UpdateLocations { get { return new RelayCommand<object>(param => this.UpdateLocationView(param), param => this.CanUpdateLocationView(param)); } } 

    void OpenIPAddress() { 
     System.Windows.Application.Current.MainWindow.Content = new AddStaticIPAddress(); 
    } 

    bool CanOpenIPAddress() { 
     return true; 
    } 
    public ICommand OpenAddNewIPAddress { get { return new RelayCommand(OpenIPAddress,CanOpenIPAddress); } } 
    #endregion 
} 

ページAddStaticIPAddress:

は、
<Page x:Class="StaticIPConfiger.AddStaticIPAddress" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:local="clr-namespace:StaticIPConfiger" 
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="500" 
    Title="AddStaticIPAddress"> 

<Page.DataContext> 
    <local:AddCustomerVModel/> 
</Page.DataContext> 
<Grid> 
    <Label x:Name="lbl_net" Content="Netz:" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/> 
    <Label x:Name="lbl_subnetmask" Content="Subetnmaske:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,36,0,0"/> 
    <Label x:Name="label_ipaddress" Content="IP Addresse:" HorizontalAlignment="Left" Margin="10,62,0,0" VerticalAlignment="Top"/> 
    <TextBox x:Name="text_net" Text="" HorizontalAlignment="Left" Height="23" Margin="103,10,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> 
    <TextBox x:Name="text_subetnmask" Text="" HorizontalAlignment="Left" Height="23" Margin="103,36,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> 
    <TextBox x:Name="text_ipaddress" Text="" HorizontalAlignment="Left" Height="23" Margin="103,62,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> 
    <Label x:Name="lbl_description" Content="Bezeichnung:" HorizontalAlignment="Left" Margin="10,85,0,0" VerticalAlignment="Top"/> 
    <TextBox x:Name="text_description" Text="" HorizontalAlignment="Left" Height="23" Margin="103,88,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="120"/> 
    <Button x:Name="btn_save_add_ip" Content="IP Addresse hinzufügen" Command ="" HorizontalAlignment="Left" Margin="10,129,0,0" VerticalAlignment="Top" Width="133"/> 
    <Button x:Name="btn_abort_add_ip" Content="Verwerfen" HorizontalAlignment="Left" Margin="148,129,0,0" VerticalAlignment="Top" Width="75"/>  
</Grid> 

AddIPAddressVModel:

namespace StaticIPConfiger.Modelle { 
    class AddIPAddressVModel : INotifyPropertyChanged { 
    IPAddress _ipaddress; 

    public AddIPAddressVModel() { 
     _ipaddress = new IPAddress { Net = "", Subetnmask = "", IpAddress = ""}; 
    } 


    public IPAddress IPAddress { 
     get { return _ipaddress; } 
     set { _ipaddress = value; } 
    } 
    #region"Get/Set" 
    public int Id { 
     get { return IPAddress.Id; } 
     set { 
      IPAddress.Id = value; 
      RaisePropertyChanged("IPAddress"); 
     } 
    } 

    public String Net { 
     get { return IPAddress.Net; } 
     set { 
      IPAddress.Net= value; 
      RaisePropertyChanged("Net"); 
     } 
    } 

    public string Subnetmask { 
     get { return IPAddress.Subetnmask; } 
     set { 
      IPAddress.Subetnmask = value; 
      RaisePropertyChanged("Subetnmask"); 
     } 
    } 

    public string IpAddress { 
     get { return IPAddress.IpAddress; } 
     set { 
      IPAddress.IpAddress = value; 
      RaisePropertyChanged("IPAddress"); 
     } 
    } 
    #endregion 

    #region INotifyPropertyChanged Members 
    public event PropertyChangedEventHandler PropertyChanged; 
    #endregion 

    #region Methods 

    private void RaisePropertyChanged(string propertyName) { 
     // take a copy to prevent thread issues 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) { 
      handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 
    #endregion 
} 

私はあなたがご質問があれば、私に知らせて、私の問題;-) を理解してほしいです。 ありがとう!

EDIT: 私はAddIPAddress を開くどのように私は私がコマンドOpenAddNewIPAddressを持っているのDataGridにコマンドをバインドしました:その別の

void OpenIPAddress() { 
    System.Windows.Application.Current.MainWindow.Content = new AddStaticIPAddress(); 
} 

bool CanOpenIPAddress() { 
    return true; 
} 
public ICommand OpenAddNewIPAddress { get { return new RelayCommand(OpenIPAddress,CanOpenIPAddress); } } 

<DataGrid.InputBindings> 
     <MouseBinding Gesture="LeftDoubleClick" Command="{Binding OpenAddNewIPAddress}" 
         CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=SelectedItem}"/> 
</DataGrid.InputBindings> 

コマンドは次のようになります私が持っていた質問。 MainWindow(System.Windows.Application.Current.MainWindow.Content =新しいAddStaticIPAddress();)の内容を新しいページで設定すると、メニューバーが失われてしまいます。これを行うより良い方法はありますか?

+0

PageAddStaticIPAddressをどのように開いていますか? – mm8

+0

私の投稿を編集しました:) –

答えて

1

あなたは、コマンドパラメータでAddIPAddressVModelを注入できます。このような何か:

<DataGrid IsReadOnly="True" Name="dg2Customers" ItemsSource="{Binding AlleStandorte}" AutoGenerateColumns="False" Margin="0,168,0,10" > 
    <DataGrid.InputBindings> 
     <MouseBinding Gesture="LeftDoubleClick" Command="{Binding OpenAddNewIPAddress}"CommandParameter="{Binding SelectedItem}"/> 
    </DataGrid.InputBindings> 
    <DataGrid.Columns> 
     <DataGridTextColumn Header="StandortId" Binding="{Binding Path=l_id}" Width="*"></DataGridTextColumn> 
     <DataGridTextColumn Header="Standort" Binding="{Binding Path=l_name}" Width="*"></DataGridTextColumn> 
    </DataGrid.Columns> 
</DataGrid> 

void OpenIPAddress(object parameter) 
{ 
    System.Windows.Application.Current.MainWindow.DataContext = new AddIPAddressVModel(parameter as DataRowView) 
    System.Windows.Application.Current.MainWindow.Content = new AddStaticIPAddress(); 
} 

bool CanOpenIPAddress(object parameter) 
{ 
    return true; 
} 

public ICommand OpenAddNewIPAddress { get { return new RelayCommand<object>(OpenIPAddress, CanOpenIPAddress); } } 

public AddIPAddressVModel(DataRowView drv) { 
    _ipaddress = new IPAddress { Net = "", Subetnmask = "", IpAddress = ""}; 
    _drv = drv; //keep a reference to the clicked DataRowView 
} 

はAddStaticIPAddressビューからこれを削除します。

<Page.DataContext> 
    <local:AddCustomerVModel/> 
</Page.DataContext> 

ページはそののDataContextを継承する必要があります。 XAMLマークアップでのDataContextの設定は、ビューモデルに依存性がない非常に単純なシナリオでのみ有効です。

+0

ありがとう、これは私がしたいように見えます;-)私はあなたのソリューションを実装しましたが概要:System.Windows.Dataエラー:40:BindingExpressionパスエラー: 'SelectedItem'プロパティが 'object' '' VModel '(HashCode = 30369281)'に見つかりません 'というエラーメッセージが表示されます。 BindingExpression:Path = SelectedItem; DataItem = 'VModel'(HashCode = 30369281);ターゲット要素は 'MouseBinding'(HashCode = 18183789)です。ターゲットプロパティは 'CommandParameter'(タイプ 'Object')です –

+0

DataContextをどのように継承しますか?私はいつもこのようにしました:/ –

+1

ページのDataContextを明示的に設定しない限り、自動的に継承されます。私が投稿したサンプルコードでは、AddIPAddressVModelのインスタンスにウィンドウのDataContextを設定し、Content(AddStaticIPAddress)がこれを継承します。 – mm8

0

AddStaticIPAddressにフィールドを配置しようとすると:

public DataGridRow Row { get; set; } 

ですから、VModelからアクセスすることができます。 など。あなたはDataGridSelectionChangedアクションにAddIPAddressVModelを初期化することができます。

private void dgCustomers_OnSelectionChanged(...) 
{ 
    AddIPAddressVModel addip = new AddIPAddressVModel(); 
    addip.Row = (DataGridRow) dgCustomers.SelectedItem; 
    addip.Show(); 
} 
+0

あなたの答えをありがとう!あなたはdgCustomerではなくDataGridを意味しますか?クラスDgCustomerは存在しないからです。私のxamlでは、私はdgCustomerによってDatagridを参照しています。ですから、AddStaticIPaddressVModelのdgCustomerフィールドを入力してください。これまではVModelで使っています。そして、VModelで_OnSelectionChanged(ここにパラメータを渡しますか?)を書いて、AddIPAddessVModelのselectedItemにアクセスできるようになりますか? –

+0

はい、 'DataGridRow'を送信したいのですが、' DataGrid'から 'DataGridRow'に簡単にアクセスできるかどうか分かりません – msmych

関連する問題