使用DisplayMemberPath时更新组合框

时间:2013-01-21 10:21:11

标签: wpf combobox mvvm-light

我正在使用WPF和MVVM轻量级框架(我是新用的)

情况如下:

  • 我有一个组合框显示项目列表(从数据库加载),我使用DisplayMemberPath显示组合框中项目的标题。

  • 在同一个GUI中,用户可以在文本框中修改项目标题。 “保存”按钮允许用户将数据保存到数据库中。

我想要做的是当用户点击“保存”时,组合框中的项目标题也会更新,并且此时会显示新值。但是,我不知道该怎么做......

我的实施的一些细节:

MainWindow.xaml

<ComboBox ItemsSource="{Binding SourceData}" SelectedItem="{Binding SelectedSourceData,Mode=TwoWay}" DisplayMemberPath="Title" />
<TextBlock Text="{Binding SelectedDataInTextFormat}"/>

MainWindow.xaml.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        Closing += (s, e) => ViewModelLocator.Cleanup();
    }
}

MainViewModel.xaml

public class MainViewModel:ViewModelBase
{
  public ObservableCollection<Foo> SourceData{get;set;}
  public Foo SelectedSourceData 
  { 
    get{return _selectedFoo;}
    set{_selectedFoo=value; RaisePropertyChanged("SelectedSourceData"); }
  }

  public string SelectedDataInTextFormat
  {
    get{return _selectedDataInTextFormat;}
    set{_selectedDataInTextFormat=value; RaisePropertyChanged("SelectedDataInTextFormat");
  }
}

如果有人能帮助我,我将不胜感激。

感谢您的帮助。

罗曼

3 个答案:

答案 0 :(得分:1)

您可能只是在SelectedSourceData更改时更新SelectedDataInTextFormat媒体资源:

public string SelectedDataInTextFormat
{
    get { return _selectedDataInTextFormat; }
    set
    {
        _selectedDataInTextFormat = value;
        RaisePropertyChanged("SelectedDataInTextFormat");

        SelectedSourceData = SourceData.FirstOrDefault(f => f.Title == _selectedDataInTextFormat)
    }
}

编辑:为了更改ComboBox中当前选定的Title项的Foo属性,您可以在Foo类中实现INotifyPropertyChanged

public class Foo : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private string title = string.Empty;
    public string Title
    {
        get { return title; }
        set
        {
            title = value;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Title"));
            }
        }
    }
}

然后只需设置所选项目的Title属性:

SelectedSourceData.Title = SelectedDataInTextFormat;

答案 1 :(得分:0)

有很多方法可以做到这一点,这个例子利用Button Tag属性将一些数据发送到保存按钮处理程序(或ICommand),然后我们可以设置TextBox UpdateSourceTriggerExplicit并在点击Button时调用更新。

示例:

的Xaml:

<Window x:Class="WpfApplication8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="105" Width="156" Name="UI">
    <Grid DataContext="{Binding ElementName=UI}">
        <StackPanel Name="stackPanel1">
            <ComboBox x:Name="combo" ItemsSource="{Binding SourceData}" DisplayMemberPath="Title" SelectedIndex="0"/>
            <TextBox x:Name="txtbox" Text="{Binding ElementName=combo, Path=SelectedItem.Title, UpdateSourceTrigger=Explicit}"/>
            <Button Content="Save" Tag="{Binding ElementName=txtbox}" Click="Button_Click"/>
        </StackPanel>
    </Grid>
</Window>

代码:

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private ObservableCollection<Foo> _sourceData = new ObservableCollection<Foo>();

    public MainWindow()
    {
        InitializeComponent();
        SourceData.Add(new Foo { Title = "Stack" });
        SourceData.Add(new Foo { Title = "Overflow" });
    }

    public ObservableCollection<Foo> SourceData
    {
        get { return _sourceData; }
        set { _sourceData = value; }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var txtbx = (sender as Button).Tag as TextBox;
        txtbx.GetBindingExpression(TextBox.TextProperty).UpdateSource();
    }


    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}


public class Foo : INotifyPropertyChanged
{
    private string _title;
    public string Title
    {
        get { return _title; }
        set { _title = value; RaisePropertyChanged("Title"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }
}

答案 2 :(得分:0)

代码:

public ObservableCollection<Foo> SourceData{get;set;}
public Foo SelectedSourceData 
{
    get{
        return _selectedFoo;
    }
    set{
        _selectedFoo=value;
        RaisePropertyChanged("SelectedSourceData");
    }
}

public string SelectedDataInTextFormat //Bind the text to the SelectedItem title
{
    get{
        return SelectedSourceData.Title
    }
    set{
        SelectedSourceData.Title=value;
        RaisePropertyChanged("SelectedDataInTextFormat");
    }
}

XAML:

<ComboBox ItemsSource="{Binding SourceData, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
    SelectedItem="{Binding SelectedSourceData,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="Title" />
<TextBlock Text="{Binding SelectedDataInTextFormat, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>