我在尝试将一个属性绑定到另一个属性时陷入困境。 这两个属性是:
我必须使用2个转换器将Content转换为字符串,并将字符串转换为Content,所以不能使用TwoWay绑定模式。
使用以下代码:
<controls:RichEditControl
x:Name="richEditControl1"
BarManager="{Binding ElementName=barManager1, Mode=OneTime}"
HorizontalRulerVisibility="Collapsed"
VerticalRulerVisibility="Collapsed"
Content="{Binding ElementName=listBoxBooks, Path=SelectedItem.End, Converter={StaticResource PlainContentConverter}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
应该有一半的绑定,但是我不知道如何实现后一半,我的意思是从listView->(Book)selectedItem->结束到Content属性。
我尝试过这样的事情:
Binding myBinding = new Binding("Content");
myBinding.Source = richEditControl1;
myBinding.Mode = BindingMode.OneWay;
listBoxBooks.SetBinding(ListView.SelectedItemProperty, myBinding);
但是这是错误的,因为我不想绑定整个SelectedItemProperty,而只绑定其“ End”属性。 (selectedItem是“ Book”类)。
谢谢。
EDIT1 我按照注释中的建议更改了后台代码,但没有成功。 代码是:
Binding myBinding = new Binding("End");
myBinding.Source = (Book)listBoxBooks.SelectedItem;
myBinding.Mode = BindingMode.OneWay;
richEditControl1.SetBinding(RichEditControl.ContentProperty, myBinding);
(实际上,它会使绑定的方向反转,但我认为第一个方向是错误的)。
答案 0 :(得分:0)
更新后,我想我了解您要执行的操作。因此,我的理解是,您拥有一本书的清单,并且在选择一本书时,您只想更新自定义控件以反映出来。
如果没有通过代码绑定的特定原因,则可以使用以下技术。 (例如,我做了一个快速演示)
第1步:设置XAML以直接绑定到Listbox.SelectedItem。
<Window x:Class="TestWPF.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:TestWPF"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Window.Resources>
<local:DummyConverter x:Key="DummyConverter"/>
</Window.Resources>
<Grid Margin="15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListBox x:Name="MyListOfBooks" ItemsSource="{Binding Path=BookCollection, Mode=OneWay}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Title, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="{Binding Path=End, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, StringFormat='dddd, dd MMMM yyyy'}" Margin="30,0,0,0"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<!--Replace with custom control, make sure your custom control has a dependancy property for this binding-->
<TextBox x:Name="MyTextBox" Grid.Column="2" Text="{Binding Path=SelectedItem.Title, ElementName=MyListOfBooks, Converter={StaticResource DummyConverter}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10"/>
</Grid>
</Window>
第2步:这是我要提供帮助的演示代码。
namespace TestWPF
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
MainViewModel model;
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
model = new MainViewModel();
model.Load();
this.DataContext = model;
}
}
public class MainViewModel
{
public ObservableCollection<Book> BookCollection { get; set; }
public void Load()
{
BookCollection = new ObservableCollection<Book>
{
new Book() { Title = "Book One", End = DateTime.Now },
new Book() { Title = "Book Two", End = DateTime.Now.AddDays(10) },
new Book() { Title = "Book Three", End = DateTime.Now.AddDays(2) }
};
}
}
public class Book : INotifyPropertyChanged
{
private string title;
private DateTime end;
public string Title
{
get { return title; }
set
{
title = value;
NotifyPropertyChanged();
}
}
public DateTime End
{
get { return end; }
set
{
end = value;
NotifyPropertyChanged();
}
}
public void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
public class DummyConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
System.Text.ASCIIEncoding encoding = new ASCIIEncoding();
return string.Join("-", encoding.GetBytes((value as string) ?? string.Empty));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null)
return null;
string val = (value as string);
var array = val.Split('-');
Byte[] byteArray = new Byte[array.Length];
for (int i = 0; i < array.Length; i++)
{
Byte.TryParse(array[i], out byte x);
byteArray[i] = x;
}
return Encoding.ASCII.GetString(byteArray);
}
}
}
如果您仍然在绑定时遇到问题,或者如果我误解了该问题,请告诉我。还提供您的自定义控件的代码。
答案 1 :(得分:0)
感谢您的回答,但是我只是找到了一个解决方案:实际上,我没有告诉您我尝试使用等于TwoWay的绑定模式,我告诉过您不可能。但是我错了,TwoWay与转换器兼容,因为转换器在每个转换方向上都包含两种方法。使用此代码是可能的:
Content="{Binding ElementName=listBoxBooks, Path=SelectedItem.End,Converter={StaticResource PlainToContentConverter},UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
,但格式丢失。我以为是由于缺少第二个转换器(在另一个方向)造成的,但是正如我刚才指出的那样,我错了。上面的代码不保留格式,因为它只是没有将其保存为纯文本!用HtmlToContentConverter替换转换器即可完成工作!
仍然感谢您度过的时间!